为什么“X”能成为输出的最后一个字符?

问题描述 投票:0回答:3
#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可能是打印为输出的最后一个字符?

c fork pid
3个回答
2
投票

我意识到waitpid等待任何子进程,所以如果打印出ZY,那么Y可以立即打印出来,因为它等待“Y”。因此,X可以作为最后一个字符打印。


0
投票

我不认为我之前在代码中使用过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

0
投票

如您所知,基于两个叉子将有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
© www.soinside.com 2019 - 2024. All rights reserved.