#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打印为输出的最后一个字符吗?
答案 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