[英]Child processes with fork
我正在嘗試制作一個簡單的C程序,該程序將調用fork
方法三次,並顯示子進程的標識符(UID,GID,PID,PPID,PGID)。 而且,我正在努力正確理解實際發生的事情。 在我的代碼中,我為方法fork()
和顯示標識符使用了單獨的方法,並且對於父進程,我試圖使用waitpid
方法來等待所有子進程死亡。 現在,我真的很困惑,因為我無法以明確表示它可以正常工作的方式使其工作。 您能給我任何建議或顯示解決我問題的更好方法嗎?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
void identifiers();
void forkMethod();
int main(void)
{
forkMethod();
return 0;
}
void forkMethod()
{
int k;
int status;
for (k=0;k<3;k++){
switch (fork()) {
case -1:
perror("fork error");
exit(EXIT_FAILURE);
break;
case 0:
identifiers();
break;
default:
//wait(&status);
waitpid(getpid(), &status, WNOHANG);
sleep(1);
break;
}
}
}
void identifiers()
{
pid_t pid = getpid();
pid_t ppid = getppid();
pid_t pgid = getpgid(pid);
pid_t uid = getuid();
pid_t gid = getgid();
printf("UID:%d GID:%d PID:%d PPID:%d PGID:%d\n", uid, gid, pid, ppid, pgid);
}
// ================================================ ===========
首先,謝謝大家的回答,並指出我犯的所有這些錯誤,
我知道代碼很可怕,可能仍然有一些問題,但是現在我想我已經想要了。
正如@John Bollinger所問,我的列表中有什么主要功能:1.編寫一個顯示指定進程的標識符UID,GUID,PID,PPID,PGID的函數2.調用fork()函數3次,並為子進程顯示這些標識符3.使用sleep功能從最舊的順序開始顯示進程。4.根據結果顯示進程樹。
謝謝@juhist和@Jonathan Leffler的簡單明了的解釋。 如果代碼中有任何重大問題,請發布
並且知道最終的代碼是:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
void identifiers(); // function that display identifiers
void forkMethod(); // function that calls fork() function 3 times
void tree(int); // function displaying processes tree
int main(void)
{
identifiers(); // displaying ID's for parent process
printf("Parent pid: %d\n", getpid());
printf("Child processes: \n");
forkMethod();
return 0;
}
void forkMethod()
{
int k;
int status;
int pid;
for (k=0;k<3;k++){
pid = fork();
switch (pid) {
case -1:
perror("fork error");
exit(EXIT_FAILURE);
break;
case 0:
identifiers();
exit(0);
default:
tree(getpid());
wait(&status);
sleep(1);
break;
}
}
}
void identifiers()
{
pid_t pid = getpid();
pid_t ppid = getppid();
pid_t pgid = getpgid(pid);
pid_t uid = getuid();
pid_t gid = getgid();
printf("\nUID:%d GID:%d PID:%d PPID:%d PGID:%d\n", uid, gid, pid, ppid, pgid);
}
void tree(int pid)
{
char pstree[] = "pstree -np ";
char cmd[12];
sprintf(cmd, "%s%d", pstree, pid);
system(cmd);
}
您的問題之一是此代碼中:
case 0:
identifiers();
break;
當然,您打算這樣做:
case 0:
identifiers();
exit(0);
否則,子進程將繼續執行,並且您將獲得太多的派生。
另一個問題是您正在使用父pid(而不是子pid)調用waitpid()。 在使用WNOHANG參數時,調用沒有任何用處。 使用wait()或將fork所返回的孩子的pid存儲在某個地方,並將該pid用作waitpid()的參數。
此外,您應該考慮檢查waitpid()的返回值。 在較大的程序中,如果您有信號處理程序,則調用可能會被信號中斷並返回錯誤代碼,錯誤代碼為errno == EINTR。 最好重試被信號中斷的系統調用,並檢查其他可能的錯誤返回。
在這行上:
waitpid(getpid(), &status, WNOHANG);
getpid()
將始終獲取父pid,而不是子pid。 建議將switch(fork())
更改為
pid= fork(); switch(pid) { ... }
和waitpid
行到
waitpid(pid, &status, 0);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.