为了帮助您理解,请在每个 printf() 语句中包含 PID 和 PPID。另外,捕获并报告wait()每次调用时返回的值(死子PID);您可以决定是否报告status,但将其初始化为零以防(何时)wait() 调用失败,因为没有孩子。一般来说,在父级从 wait() 调用返回之前,子级会继续。
或者,更好的是,编写一个可以为您处理详细信息的日志记录函数。
例如,考虑以下代码:
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
static void print_info(const char *tag, int corpse, int status, int child)
{
int pid = getpid();
int ppid = getppid();
printf("PID %5d, PPID %5d: %s (corpse: %5d, status 0x%.4X), child %5d\n",
pid, ppid, tag, corpse, status, child);
}
int main(void)
{
int pid = getpid();
int ppid = getppid();
printf("Initial PID %5d, PPID %5d:\n", pid, ppid);
int status = 0;
int child = fork();
int corpse = wait(&status);
print_info("a", corpse, status, child);
child = fork();
corpse = wait(&status);
print_info("b", corpse, status, child);
child = fork();
corpse = wait(&status);
print_info("c", corpse, status, child);
child = fork();
corpse = wait(&status);
print_info("d", corpse, status, child);
return 0;
}
一个示例运行给了我:
Initial PID 7357, PPID 20754:
PID 7358, PPID 7357: a (corpse: -1, status 0x0000), child 0
PID 7359, PPID 7358: b (corpse: -1, status 0x0000), child 0
PID 7360, PPID 7359: c (corpse: -1, status 0x0000), child 0
PID 7361, PPID 7360: d (corpse: -1, status 0x0000), child 0
PID 7360, PPID 7359: d (corpse: 7361, status 0x0000), child 7361
PID 7359, PPID 7358: c (corpse: 7360, status 0x0000), child 7360
PID 7362, PPID 7359: d (corpse: -1, status 0x0000), child 0
PID 7359, PPID 7358: d (corpse: 7362, status 0x0000), child 7362
PID 7358, PPID 7357: b (corpse: 7359, status 0x0000), child 7359
PID 7363, PPID 7358: c (corpse: -1, status 0x0000), child 0
PID 7364, PPID 7363: d (corpse: -1, status 0x0000), child 0
PID 7363, PPID 7358: d (corpse: 7364, status 0x0000), child 7364
PID 7358, PPID 7357: c (corpse: 7363, status 0x0000), child 7363
PID 7365, PPID 7358: d (corpse: -1, status 0x0000), child 0
PID 7358, PPID 7357: d (corpse: 7365, status 0x0000), child 7365
PID 7357, PPID 20754: a (corpse: 7358, status 0x0000), child 7358
PID 7366, PPID 7357: b (corpse: -1, status 0x0000), child 0
PID 7367, PPID 7366: c (corpse: -1, status 0x0000), child 0
PID 7368, PPID 7367: d (corpse: -1, status 0x0000), child 0
PID 7367, PPID 7366: d (corpse: 7368, status 0x0000), child 7368
PID 7366, PPID 7357: c (corpse: 7367, status 0x0000), child 7367
PID 7369, PPID 7366: d (corpse: -1, status 0x0000), child 0
PID 7366, PPID 7357: d (corpse: 7369, status 0x0000), child 7369
PID 7357, PPID 20754: b (corpse: 7366, status 0x0000), child 7366
PID 7370, PPID 7357: c (corpse: -1, status 0x0000), child 0
PID 7371, PPID 7370: d (corpse: -1, status 0x0000), child 0
PID 7370, PPID 7357: d (corpse: 7371, status 0x0000), child 7371
PID 7357, PPID 20754: c (corpse: 7370, status 0x0000), child 7370
PID 7372, PPID 7357: d (corpse: -1, status 0x0000), child 0
PID 7357, PPID 20754: d (corpse: 7372, status 0x0000), child 7372
你可以追查数据,看到4个fork()调用有24个进程(每次调用之后,有2个进程,之前有1个进程,所以在1个之后调用有 2 个进程;在 2 次调用之后,有 4 个进程;依此类推),并且子进程在父进程继续之前退出(因此,在此示例中,PID 7357 是最后一个打印 a 标记的,和b 标签、c 标签和d 标签)。
当您在跟踪流程树时遇到困难时,请使用与此类似的打印技术来帮助您更好地了解正在发生的事情。