fork()系统调用以什么方式调用子进程?

时间:2011-12-06 09:41:38

标签: c unix fork

这是我的fork()系统调用代码,

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<errno.h>
int main(int argc, char *argv[])
{
 pid_t pid;
 pid=fork();
 printf("1st Fork\n");
 printf("Process ID : %d, Parent Process ID : %d\n",getpid(),getppid());
 pid=fork();
 printf("2nd Fork\n");
 printf("Process ID : %d, Parent Process ID : %d\n",getpid(),getppid());
 pid=fork();
 printf("3rd Fork\n");
 printf("Process ID : %d, Parent Process ID : %d\n",getpid(),getppid());
 return 0;
}

在运行代码时,我得到像

这样的输出
1st Fork
Process ID : 3393, Parent Process ID : 3392
2nd Fork
Process ID : 3394, Parent Process ID : 3393
3rd Fork
Process ID : 3395, Parent Process ID : 3394
3rd Fork
Process ID : 3394, Parent Process ID : 3393
2nd Fork
Process ID : 3393, Parent Process ID : 3392
3rd Fork
Process ID : 3397, Parent Process ID : 3393
3rd Fork
Process ID : 3393, Parent Process ID : 3392
1st Fork
Process ID : 3392, Parent Process ID : 3440
2nd Fork
Process ID : 3398, Parent Process ID : 3392
3rd Fork
Process ID : 3400, Parent Process ID : 3398
3rd Fork
Process ID : 3398, Parent Process ID : 3392
2nd Fork
Process ID : 3392, Parent Process ID : 3440
3rd Fork
Process ID : 3401, Parent Process ID : 3392
3rd Fork
Process ID : 3392, Parent Process ID : 3440

为什么这个fork()系统调用8进程以及如何进行?

我也得到了14个printf()语句执行。为什么呢?

4 个答案:

答案 0 :(得分:3)

每次拨打fork时,都会返回两次。一旦进入父母,一旦进入新的过程。然后当他们继续时,他们都再次分叉

你很可能没想到孩子再次分叉。每个fork通常都有:

switch (fork()) {
case -1:
    /* ERROR. */
    break;
case 0:
    /* Child process. */
    break;
default:
    /* Parent. */
    break;
}

在您的代码中,它是这样的:

  • 您有一个流程,然后它分叉
  • 您现在有两个进程,都是fork
  • 您现在有4个流程,所有这些流程
  • 您现在有8个流程,而您正在询问有关SO
  • 的问题

答案 1 :(得分:2)

我建议你仔细看看你的输出 - 有 8个进程:

$ cat <<EOF | sort -u
> 1st Fork
> Process ID : 3393, Parent Process ID : 3392
> 2nd Fork
> Process ID : 3394, Parent Process ID : 3393
> 3rd Fork
> Process ID : 3395, Parent Process ID : 3394
> 3rd Fork
> Process ID : 3394, Parent Process ID : 3393
> 2nd Fork
> Process ID : 3393, Parent Process ID : 3392
> 3rd Fork
> Process ID : 3397, Parent Process ID : 3393
> 3rd Fork
> Process ID : 3393, Parent Process ID : 3392
> 1st Fork
> Process ID : 3392, Parent Process ID : 3440
> 2nd Fork
> Process ID : 3398, Parent Process ID : 3392
> 3rd Fork
> Process ID : 3400, Parent Process ID : 3398
> 3rd Fork
> Process ID : 3398, Parent Process ID : 3392
> 2nd Fork
> Process ID : 3392, Parent Process ID : 3440
> 3rd Fork
> Process ID : 3401, Parent Process ID : 3392
> 3rd Fork
> Process ID : 3392, Parent Process ID : 3440
> EOF
1st Fork
2nd Fork
3rd Fork
Process ID : 3392, Parent Process ID : 3440
Process ID : 3393, Parent Process ID : 3392
Process ID : 3394, Parent Process ID : 3393
Process ID : 3395, Parent Process ID : 3394
Process ID : 3397, Parent Process ID : 3393
Process ID : 3398, Parent Process ID : 3392
Process ID : 3400, Parent Process ID : 3398
Process ID : 3401, Parent Process ID : 3392

八个流程有意义:您的程序中有三个fork(2)个调用,每个fork(2)调用都会复制正在运行的进程。由于三个fork(2)调用不会通过分支相互保护,因此所有三个调用都将执行: 2 ^ 3 == 8

<强>更新

我喜欢Chris's display,但想要纠正有15个总进程的想法。因此,我将使用每个过程的不同符号修改他的三角形:

        ~
    ~       $
  ~   @   $   ^
 ~ ! @ # $ % ^ &

答案 2 :(得分:2)

fork()的目的是创建一个新进程,该进程成为调用者的子进程。

创建新的子进程后,两个进程都将执行fork()系统调用之后的下一条指令。

因此,在您的代码中,每个fork都会生成两个不同的执行路径,如高度为4的二叉树。

        *
    *       *
  *   *   *   *
 * * * * * * * * 

总共有15个节点,这意味着你创建了14个其他进程。

答案 3 :(得分:1)

每次调用fork()时,都会从该点创建父进程的副本,称为子进程。 所以,在第一次分叉之后你有两个进程(子进程和父进程) 同样, 第二个fork()将在上面两个进程中调用,这导致另外两个进程。 同样,乘法还在继续。