#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
if (fork() == fork()){
fprintf(stderr, "Z");
}
else {
if (waitpid((pid_t)-1,NULL,0)!=-1) {
fprintf(stderr, "Y");
}
else {
fprintf(stderr, "X");
}
}
}
我正在研究这个程序,我发现“ZYYX”可以作为输出。我不太明白为什么。根据我的理解,总共有四个过程,parent-> parent,parent-> child,child-> parent,child-> parent。并且毫无疑问,孩子 - >儿童版画Z.并且孩子 - >父母在孩子 - >孩子打印Z之后打印Y.父母 - >父母应该等到父母 - >孩子打印X.那么为什么X可能是打印为输出的最后一个字符?
我意识到waitpid等待任何子进程,所以如果打印出ZY,那么Y可以立即打印出来,因为它等待“Y”。因此,X可以作为最后一个字符打印。
我不认为我之前在代码中使用过if (fork() == fork())
- 恭喜!我并不完全相信你的追踪;我想看看它所做的任何打印中包含的每个进程的PID,我想在每个输出的末尾都有一个换行符。此外,原始代码中至少有一个进程没有等待。
这是一个重写,它报告每个打印操作的进程的PID。一些进程以非零状态退出,主要是为了使它在输出中更有趣。该代码跟踪检测到的尸体并报告其状态。它还引入了一个循环来清理死去的孩子。原始流程有一个孩子,否则不会被清理。
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void)
{
if (fork() == fork())
{
fprintf(stderr, "Z(%d)\n", (int)getpid());
return 23;
}
else
{
int corpse;
int status;
if ((corpse = waitpid((pid_t)-1, &status, 0)) != -1)
fprintf(stderr, "Y(%d) - PID %d 0x%.4X\n", (int)getpid(), corpse, status);
else
{
fprintf(stderr, "X(%d)\n", (int)getpid());
return 37;
}
while ((corpse = waitpid((pid_t)-1, &status, 0)) != -1)
fprintf(stderr, "Q(%d) - PID %d 0x%.4X\n", (int)getpid(), corpse, status);
}
return 0;
}
样本输出:
X(16551)
Y(16547) - PID 16551 0x2500
Z(16552)
Y(16550) - PID 16552 0x1700
Q(16547) - PID 16550 0x0000
如您所知,基于两个叉子将有4个进程,每个进程将打印一个字母:
1st fork 2nd fork prints PP
parent parent Y / \
parent child X CP PC
child parent Y \
child child Z CC
左边的图表显示了父/子关系 - /
是第一个fork,\
是第二个fork。
所以CC打印Z
因为两个forks都返回0,而PC打印X
。其他两个都等待孩子退出,然后打印Y
。在CP的cas中,只有一个孩子,所以Y
总是在Z
之后,但PP有两个孩子,所以Y
可能在ZY
之后或在X
之后。要么是可能的。所以你可以得到任何一个
XYZY PC,PP,CC,CP
XZYY PC,CC,PP,CP or PC,CC,CP,PP
ZXYY CC,PC,PP,CP or CC,PC,CP,PP
ZYXY CC,CP,PC,PP
ZYYX CC,CP,PP,PC