计算fork()代码中的进程总数

时间:2017-09-24 08:26:23

标签: c linux fork

我正在尝试确定以下代码中有多少个进程:

#include <stdio.h>
#include <unistd.h>

int main() {  

int i = 1;

   if (fork ()) //parent process will return PID of child.
        i++;
   else if (fork()) //child process (becomes parent)
            i--;
       else //grandchild process returns 0
            i++;

 printf("%d\n", i);
}

通常,进程总数的公式为2 ^ n,其中n是fork系统调用的数量。我很困惑因为这个样本涉及if / else条件语句。

我总共得到4个进程。 (来自 if(fork())语句的2个进程和 elseif(fork())语句中的2个进程。有人可以确认这是否正确?如果没有,请你指导我正确的方向/解释如何计算进程数。这是我在确定时遇到的一些麻烦。

谢谢大家。

2 个答案:

答案 0 :(得分:1)

注意:即使if ()未成功,true语句也会被评估为fork(),因为在这种情况下,它会返回与0不同的负数所以true

您有3个流程

第一个fork()生成父进程的副本,即子进程。现在你有2个进程。 fork()将子PID返回给父级。这使得父级的第一个if()条件true和子级的false。父级递增变量i

因此,子流进入第二个if语句,该语句在被evalated之前执行fork。 fork生成一个孩子的副本(现在成为父母),即孙子。您现在有3个流程。

子项评估else if条件true,并在孙子评估i时递减false,并递增i

就我所说的而言,如果你尝试执行你的程序,你将只获得3个输出(3 printf()已执行)。输出的顺序取决于CPU调度程序如何调度进程,以及它无法预测的内容。

答案 1 :(得分:1)

代替您的代码,试试这个:

#include <stdio.h>
#include <unistd.h>

int main()
{
    int counter = 0;

    if( fork() )
    {
        // should be the parent
        fprintf( stderr, "1. process ID: %d\n", getpid() );
        fprintf( stderr, "1. parent process ID: %d\n", getppid() );
        ++counter;
    }
    else
    if( fork() )
    {
        fprintf( stderr, "2. process ID: %d\n", getpid() );
        fprintf( stderr, "2. parent process ID: %d\n", getppid() );
        --counter;
    }
    else
    {
        fprintf( stderr, "3. process ID: %d\n", getpid() );
        fprintf( stderr, "3. parent process ID: %d\n", getppid() );
        ++counter;
    }

    printf( "counter: %d\n", counter );
}

以下是正在运行的代码的输出:

ALP ❱ gcc temp.c
ALP ❱ ./a.out 
1. process ID: 6672
1. parent process ID: 3037
counter: 1
2. process ID: 6673
2. parent process ID: 6672
counter: -1
3. process ID: 6674
3. parent process ID: 2008
counter: 1
ALP ❱ ps
  PID TTY          TIME CMD
 3037 pts/2    00:00:01 bash
 5354 pts/2    00:00:00 redshift
 6642 pts/2    00:00:00 ps
ALP ❱ ps -e | grep 2008
 2008 ?        00:00:00 upstart
ALP ❱ 

现在发生了什么:

我的计算机上

3037进程ID 2008upstart的进程ID(=在此处理僵尸进程)
6672main功能的进程ID 6673第一个孩子进程,其父母是主要的:6672
6674第二个孩子进程,2008(=暴发户)成为其父母

虽然我不确定,但我猜你在主要方面有 2 子进程,因此 3 总计。由于您未检查-1调用fork(2)失败,因此运行代码的其他人可能会有所不同。

注意
由于您的孩子和主要退出没有wait(2)而没有终止它们,upstart(8)负责终止它们。

注2
您不应该以这种方式使用fork(2)