与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 ,打印ab的值,然后退出。

父进程首先等待子进程终止。 只有在孩子完成后才继续,从b减去5,打印ab ,然后退出。

wait(NULL)确保子进程的打印输出始终位于父进程之前,因此您将始终以可靠的顺序获得相同的输出。 没有它,你将无法依赖两个打印输出的顺序。 它们将是相同的消息,只是以不可预测的顺序。

  1. a设置为12, b设置为9。

  2. fork被调用,我们现在有两个进程。

  3. 父级获取子级的PID,然后转到else子句。 子项获得0,并转到if子句。

  4. 父母等待孩子完成。

  5. 孩子增加了它的副本。 所以a现在是孩子的13岁,父母的12岁。

  6. 孩子退出,输出139

  7. 父项从其b副本中减去5,因此b在父项中现在为4。

  8. 父母退出,输出124

请注意,不保证fork之后子级和父级的确切执行顺序,但它不会更改结果,因为父级在执行任何操作之前等待子级完成。

另外,请注意两个进程正常退出是不好的做法。 当一个进程正常退出时,它会运行清理处理程序,这可能会混淆其他进程,例如通过更改共享文件描述上的文件位置,从而导致数据损坏。

当你调用fork() ,包括所有内存/变量等在内的整个过程都是重复的。

因此在fork调用之后,每个进程都有自己的ab副本,分别从129开始。

进程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。 受一个进程影响的其他进程将无法看到,因为两个进程都在自己的副本上工作