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

时间:2017-12-16 20:13:53

标签: c fork pid

#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-&gt; parent,parent-&gt; child,child-&gt; parent,child-&gt; parent。并且毫无疑问,孩子 - &gt;儿童打印Z.并且孩子 - >父母在孩子打印Y后 - >儿童打印Z.而父母 - >父母应该等到父母 - >儿童打印X.那么为什么呢有可能将X打印为输出的最后一个字符吗?

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分: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

答案 2 :(得分:0)

正如您所说,基于两个叉子将有4个过程,每个过程将打印一个字母:

 public function updateMaterial($request, $id)
{
    $material = Material::find($id);
    if (!$material)
        return false;

    if ($request->has('unit'))
        $material->unit = $request['unit'];
    if ($request->has('price'))
        $material->price = $request['price'];
    if ($request->has('type'))
        $material->type = $request['type'];
    if ($request->has('is_active'))
        $material->is_active = $request['is_active'];

    $material->updated_at = Carbon::now();

    $material->save();
    return $material;
}

左边的图表显示了父/子关系 - 1st fork 2nd fork prints PP parent parent Y / \ parent child X CP PC child parent Y \ child child Z CC 是第一个分支,/是第二个分支。

因此CC打印\因为两个forks都返回0,而PC打印Z。其他两个都等待孩子退出,然后打印X。在CP的cas中,只有一个孩子,因此Y将始终位于Y之后,但PP有两个孩子,因此Z可能位于Y之后}或ZY之后。要么是可能的。所以你可以得到任何

X