2016-06-09 27 views
0

我在阅读关于fork函数以及它如何创建新进程。下面的程序运行正常,并打印here十六倍,但是,我无法理解的执行流程:了解POSIX - fork()

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <limits.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <pthread.h> 

int main() 
{ 
    int i; 
    for (i = 0; i < 4; i++) { // line no. 12 
     fork();    // line no. 13 
    } 
    printf("%s\n", "here"); 
    return 0; 
} 

在我看来,有两种方式这个程序可以被看作是:

第一种方法:fork()总共被称为四次。如果我用四次调用fork()函数替换循环,事情似乎落空了,我明白为什么here打印2^4次。

第二种方法:fork()产生一个新的进程,从它被调用的地方开始,每个子进程都有自己的局部变量。所以,在行号后。 13,每个子进程都会看到循环的结尾(}),并且它们会转到第1行。 12.因为,所有这些子进程都有自己的局部变量i设置为0(也许i被设置为一些垃圾值?),他们都再次分叉。再次对于这些子进程,其本地变量i设置为0.这应该导致fork bomb

我当然错过了我的第二种方法可能有人请帮忙吗?

谢谢。

回答

3

你的第二种方法是不正确的。因为fork()之后子进程继承当前i。每次调用0时都不会调用fork(),也不会有垃圾值。所以,你的代码不能有叉形炸弹。它是一个局部变量的事实是无关紧要的。 fork()克隆几乎所有的东西,子过程与其父项相同,除了POSIX手册中指出的某些事项。

我会减少循环计数,以2为便于解释,并承担所有fork()通话成功:

for (i = 0; i < 2; i++) { 
     fork(); 
    } 
    printf("%s\n", "here"); 

1)当i=0fork()被执行,有两个进程了。称他们为P1和P2。

2)现在,每个P1和P2处理继续,其中i = 0的回路,并递增i为1。for循环条件为真,那么它们中的每产生另一个两道工序和在总4.打电话给他们P1A & P1b和P2a & P2b。现在所有4个进程都有i = 1并将其增加到2(因为它们继续循环)。

3)现在,所有4个进程的值为i为2,并且for循环条件在所有这些中都为false,并且“here”将被打印4次(每个进程一个)。

如果有帮助,您可以将for循环转换为while循环,以及如何i得到由过程从每个fork()返回增量可能成为多一点明确:

i = 0; 
    while(i < 2) { 
     fork(); 
     i++; 
    } 
    printf("%s\n", "here"); 
+0

精彩讲解,谢谢。 – babon

0

你的第一种方法是对。
这是一个相当无聊的答案,所以我会给你所有的技术细节。

fork叫,几件事情发生:

  • 一个新的进程创建(“孩子”)
  • 父的堆被复制,并分配给了孩子。
  • 子级的堆栈指针设置为父级的堆栈指针。
  • 孩子的PID(进程ID)返回给父级。
  • 零返回给孩子申报

变量里面函数存储在堆栈,因此在相同的值开始,但共享。
声明的变量以外函数(在顶层)不在堆栈中,所以在父/子之间共享。

(有些事情还是不重复;看到man fork以获取更多信息。)

所以,当你运行你的代码:

what happens     # of processes 
1. the parent forks.    2 
2. the parent and it's child fork. 4 
3. everyone forks     8 
4. everyone forks     16 
5. everyone prints "here".   16 

您十六个过程结束,字'这里'十六次。

基本上,

if(fork() != 0) { 
    parent_stuff(); 
} else { 
    child_stuff(); 
} 
+0

当你说'在函数外部声明的变量是共享的'时,你的意思是说,任何由子进程写入该变量对父进程都是可见的?如果你的意思是这样,我认为你错了。感谢您的回复。 – babon

+0

我99%确定它是正确的,但是'man fork'并没有提到它。 – Blacksilver

+0

那么你会如何解释这里列出的程序的输出:http://hastebin.com/owedavelob.xml – babon