[英]What happens when fork() in a condition?
谁能给我这个代码的输出(有解释)? 谢谢...
#include <stdio.h>
#include <unistd.h>
int main()
{
if (fork() && (!fork())) {
if (fork() || fork()) {
fork();
}
}
printf("Friend\n");
return 0;
}
在进入代码之前最好先了解什么是 fork() 系统调用
fork() 系统调用由“父”创建一个新进程,新创建的进程称为“子”进程
当fork成功时,子进程返回0,父进程返回正整数
这就是这里的线索
因此,从该程序计数器开始,所有两个进程都同时工作......
在这里 fork() 处于 if 条件,并且在猜测输出时也有点棘手
首先 fork() 创建新的 C1 -> 0
第二个 fork() 创建新的 C2 -> !0 -> 1
所以第一个条件由 C2(其父正整数和 c2 为 0)统计,但未由父或子 C1 统计,因此其他分叉将不起作用
然后 C2 进入另一个 if 条件并制作另外两个叉子
C2
/ \
C2 C3
/ \ / \
C2 c4 c3 c5
然后所有创建的进程(包括父进程)打印“朋友”输出 7 次
快速回答是父母会做某事,而孩子会做其他事情。 但是继续阅读……
好吧,我只是稍微修改了您的代码,您将从程序的输出中获得所有进程层次结构,以及您问题的答案:
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
static pid_t my_fork() /* tracing is your friend! :) */
{
pid_t chld = fork();
if (chld > 0) {
/* only the parent shows this */
printf("[pid=%d, child=%d] forked!\n",
getpid(), chld);
}
return chld;
}
int main()
{
/* print our pid, so we know the root of the hierarchy */
printf("[pid=%d] Hello, world\n", getpid());
/* do the embarrasing work */
if (my_fork() && (!my_fork())) {
if (my_fork() || my_fork()) {
my_fork();
}
}
pid_t pid;
int status;
/* We do wait(2)'s while there are children to be waited for.
* it's a good thing to wait for children before ending. */
while((pid = wait(&status)) >= 0) {
printf("[pid=%d, child=%d]: child ended with status=%d\n",
getpid(), pid, status);
}
/* we print the message when no more children are alive */
printf("[pid=%d]: Hello friend!\n", getpid());
return 0;
}
这会产生
$ pru
[pid=72699] Hello, world
[pid=72699, child=72700] forked!
[pid=72699, child=72701] forked!
[pid=72700]: Hello friend!
[pid=72701, child=72702] forked!
[pid=72703]: Hello friend!
[pid=72699, child=72700]: child ended with status=0
[pid=72702, child=72703] forked!
[pid=72702, child=72705] forked!
[pid=72702, child=72703]: child ended with status=0
[pid=72705]: Hello friend!
[pid=72704]: Hello friend!
[pid=72701, child=72704] forked!
[pid=72701, child=72704]: child ended with status=0
[pid=72702, child=72705]: child ended with status=0
[pid=72702]: Hello friend!
[pid=72701, child=72702]: child ended with status=0
[pid=72701]: Hello friend!
[pid=72699, child=72701]: child ended with status=0
[pid=72699]: Hello friend!
这是层次结构:
[pid=72699] (says Hello, world, just starting)
+-[pid=72700] (created in first fork() call of pid=72699)
`-[pid=72701] (created in second fork() call of pid=72699)
+-[pid=72702] (created in third fork() call of pid=72701)
| +-[pid=72703] (created in fourth fork() call of pid=72702)
| `-[pid=72705] (created in fifth fork() call of pid=72702)
`-[pid=7204] (created in fourth fork() call of pid=72701)
(当然,如果进程用完了,层次会不一样, fork(2)
因为系统资源不足而失败)
最后,您可能会担心为什么消息
[pid=72703]: Hello friend!
出现在消息之前
[pid=72702, child=72703] forked!
但这就是多任务处理的奇妙世界。 在fork(2)
返回后打印消息,因此两条消息由不同的进程打印,因此,它们可以按任何顺序进行调度,因此子进程在父进程有机会打印谁是他的孩子。 这是完全正常的。
您必须注意fork()
在出错时返回-1
,它在布尔测试中评估为true
,就像父级的结果一样。 因此,如果您自由地将fork(2)
的返回代码用于布尔表达式,则父级将收到true
或fork()
失败时发生的任何错误(好吧,它们很少,但它们在加载的系统上是可能的)。 只需保存fork()
的结果代码并首先检查错误,然后您就可以随意使用任何您想要的布尔表达式。
上面的源代码可以在这里下载
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.