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