我很难理解fork()命令在不同场景下的作用。以下是我的书中的一些示例代码:
int main() {
int a = 12;
int b = 9;
int fid = fork();
if (fid == 0) {
a++;
}
else {
wait(NULL);
b = b - 5;
}
printf("program exit. a = %d, b = %d\n", a, b);
return 0;
}
在这种情况下,有人可以告诉我fork()命令正在做什么,并且可能会提供一些示例来澄清吗?
答案 0 :(得分:12)
[main]
a = 12
b = 9
fork()
|
|
+--------------+--------------+
| |
| |
[parent] [child]
fid = 1234 fid = 0
wait(NULL) a++
... printf("a = 13, b = 9");
... return 0
... <exit>
b = b - 5
printf("a = 12, b = 4");
return 0
<exit>
执行fork()
后,程序有两个副本。每个进程都有自己的变量副本,因此现在有两个a
,两个b
等。两个程序之间的唯一区别是从{{1}返回的值}:在子进程中fork()
返回0;在父进程中,它返回子进程的PID。
子进程增加fork()
,打印a
和a
的值,然后退出。
父进程首先等待子进程终止。只有在孩子完成后才会继续,从b
减去5,打印出b
和a
,然后退出。
b
确保子进程的打印输出始终位于父进程之前,因此您将始终以可靠的顺序获得相同的输出。没有它你将无法依赖两个打印输出的顺序。它们将是相同的消息,只是以不可预测的顺序。
答案 1 :(得分:4)
a
设为12,b
设为9.
fork
被调用,我们现在有两个过程。
父级获取子级的PID,并转到else
子句。孩子得0,然后转到if
子句。
父母等待孩子完成。
儿童递增a
的副本。因此a
现在在孩子中为13,在父母中为12。
孩子退出,输出13
和9
。
家长从b
的副本中减去5,因此b
现在在家长中为4。
家长退出,输出12
和4
。
请注意,fork
之后的子项和父项的确切执行顺序无法保证,但它不会更改结果,因为父项在执行任何操作之前等待子项完成。
另外,请注意两个进程正常退出是不好的做法。当一个进程正常退出时,它会运行清理处理程序,这可能会混淆其他进程,例如通过更改共享文件描述上的文件位置,导致数据损坏。
答案 2 :(得分:3)
当您致电fork()
时,整个过程(包括所有内存/变量等)都会重复。
在fork
调用之后,每个进程都拥有自己的a
和b
副本,分别以12
和9
开头。
进程0将增加它自己的a
副本。过程1将减少(由5)它自己的b
。
所以他们应该打印:
Process 0: a = 13, b = 9
Process 1: a = 12, b = 4
答案 3 :(得分:0)
它的o / p会是 父:: a = 12,b = 4 孩子:: a = 13,b = 9
因为两个进程同时执行但两者都有不同的局部变量副本a,b 所以局部变种。受一个流程影响的流程将不会被另一个流程看到,因为两个流程都在处理他们自己的副本