通过一个简单的例子了解C'S fork()的(Understanding C's f

2019-08-17 08:31发布

#include <stdio.h>
int num = 0;
int main(int argc, char*argv[]){
    int pid;
    pid = fork();
    printf("%d", num);  
    if(pid == 0){       /*child*/
        num = 1;
    }else if(pid > 0){  /*parent*/
        num = 2;
    }
    printf("%d", num);
}

我无法理解为什么可能的输出将是0102或0012或0201或0021。

以下是我(觉得)应该生产。 它遇到第一个printf语句和物质没有什么孩子或父母最先被执行,NUM还没有被第一修改,以便0。 THEN下是1或2,再接下来的过程执行,从而从0开始再次(从父拷贝),然后或者是1或2试。 所以可能的输出应该是:

0101或0102或0201或0202

Answer 1:

在父母和孩子都,num为0,第一个printf 。 在父和子二者,0被印刷接着是其他值。 在父进程,其它值是2。在子进程,其它值是1。

然而,要注意的重要的一点是,虽然每个过程有一个强迫为了使零的另一号码之前要打印的,对相对于彼此的两个过程的打印没有限制。

这里有一个现实生活中的比喻:假设我的同事和我的每个工作留在同一时间,停在杂货店,然后下班回家。 我们知道,我是在商店前,我在我家,我们知道他是在杂货店,他在他的家了。 但是,我们不知道是谁在杂货店第一,或者谁在家里第一次。 我们可以在每个到达大约在同一时间的杂货店,然后将每个大约在同一时间下班回家,也许他的延迟,我得到的杂货店和家庭,他甚至已经开始在商店之前。

事情不会发生的是1打印或2不止一次。 虽然后fork返回我们有概念上同时运行相对于两道工序,以及它们的事件的时间彼此是未指定的,在每个进程的事件的顺序被很好地定义。 每个进程将设置num为1或2再次打印之前,并且因为fork被定义为在儿童和儿童的父PID返回0,它们将分别设置为不同的值。

还有就是,其实,另一种合理的输出: 00 。 如果fork无法创建新的进程,则返回-1。 在这种情况下,程序将打印0时, ifelse if旨意失败,因为-1既不是0也不大于0,NUM没有改变,程序打印0一次。

如果你想学习了很多关于在C程序的影响排序的定义,关键词搜索的“序列点”。 在这个程序是相当简单的(除了一个事实,即我们必须同时运行一分式两份),但有时也可能不太明显。



Answer 2:

这不是问题fork() 。 它是printf()printf()缓冲。 通常情况下,缓冲器被刷新,当它在末尾,“\ N”遇到换行符。 不过既然你已经忽略这一点,缓冲区的内容保持,不冲洗。 最后,这两个过程(原始和孩子)将具有与它为0或1的输出缓冲器。 当它最终被刷新,你会在这两个过程中看到这一点。

添加fflush(stdout); 之后printf()和尝试。



文章来源: Understanding C's fork() through a simple example
标签: c fork concept