在C丛林中用叉子砍伐树木时,我尝试重复并学习更多高级用法和选项。但是我发现一个非常简单的例子,因为我之前使用过叉子甚至编写了一些代码,但是我无法理解它。
来了:
main() {
if (fork() == 0) {
if (fork() == 0) {
printf("3");
}
else if ((wait(NULL)) > 0) {
printf("2");
}
}
else {
if (fork() == 0) {
printf("1");
exit(0);
}
if (fork() == 0) {
printf("4");
}
}
printf("0");
return 0;
}
可能的解决方案是:
其中2,5和6是正确的答案。
首先,输出中不应该有四个零吗? 第二......一个人如何解决问题?在纸上做了差不多一个小时,我甚至都没有理解为什么给定的解决方案比假的更正确(除了nr3,因为它不能以2结束,因为必须遵循0)。
任何检查过他的叉子的人谁可以提供一些好的解释?
编辑:
发现这个here从2009年开始看pdf。人们现在可以停止发布关于这是一个家庭作业的帖子并且实际上试图提供帮助吗?如果没有,请找一些其他主题来花时间。谢谢!
答案 0 :(得分:10)
我认为应该有4个零,这就是我看到的,如果我运行你的代码......
分析这个的一个好方法是绘制一个这样的图表 - 我已经将叉子显示为*
,其中父级水平延续,下面的子项,所以每个单独的过程都是单独的行:
----*----*----*----0----exit (return from main)
| | |
| | +----4----0----exit (return from main)
| |
| +----1----exit (explicitly)
|
+-----*----wait----2----0----exit (return from main)
|
+----3----0----exit (return from main)
现在很容易看到,由于wait()
,您必须在3
,之前看到0
,之后看到2
}后跟0
。
答案 1 :(得分:4)
由于程序打印后的exit
语句,输出中只有三个零。该语句立即结束该过程。 Ed:不,实际上应为4个零;我忽略了原来的过程。我不知道为什么答案中没有四个零。
在分析问题的答案时,您通常需要了解的是:
fork()
时,您都会创建一个新流程,旧流程也将继续,同时也是如此fork
的返回值来判断您是处于“旧流程”还是“新流程”中。如果您在新流程中,它将为0(假),如果您在旧流程中,则为非零(真)。wait(NULL)
将暂停当前进程的执行,直到一个分叉的进程完成。详细说明4,假设您有两个进程,一个打印“abc”,另一个打印“xyz”。诸如“abxcyz”,“xaybcz”或“xyabcz”的输出是可能的,因为序列abc和xyz各自按顺序出现。但是,输出“abzcxy”是不可能的,因为z无法在x之前出现,因为它们都来自同一个进程,而打印它们的语句则以其他顺序出现。
答案 2 :(得分:1)
他们假设当你调用wait(NULL)时,整个'3'分支将执行。这包括在该分叉的末尾打印'0'。因此答案1和4是不正确的,因为它们在'2'之前没有'0'。
至于为什么没有四个'0',我不知道。
答案 3 :(得分:0)
首先,您必须选择的选项是不所有可能的输出排列。相反,他们只是其中的一小部分。查看源代码,我们可以注意到一些消除可能性的事情:
exit(0)
而不会打印“0”。所以输出中只有三个0。也是因为这个原因,最后一个字符必须是0或1。wait(NULL)
。这意味着我们等待的孩子在打印2之前将始终打印3后跟0。这些确实是唯一能够明确说明这个问题的事情。这意味着任何正确的答案必须以0或1结束,并且必须在2之前同时具有3和0.满足这些标准的唯一答案是2,5和6。