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

问题描述 投票:0回答:2

我试图确定以下代码中生成了多少个进程:

#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 个过程和来自
else if (fork())
语句的 2 个过程)。 有人可以确认这是否正确吗?如果没有,您能否指导我正确的方向/解释如何计算进程数。 这是我很难确定的事情。

c linux fork
2个回答
2
投票

注意:即使

if ()
没有成功,
true
语句也会被评估
fork()
,因为在这种情况下它返回一个与
0
不同的负数,所以
true

您有3个进程

第一个

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

因此,子流程进入第二个 if 语句,该语句在求值之前执行 fork。分叉生成子级的副本(现在成为父级),即孙级。您现在有 3 个进程。

孩子评估

else if
条件
true
并将减少
i
,而孙子评估
false
并将增加
i

正如我所说,如果你尝试执行你的程序,你只会得到 3 个输出(3 个

printf()
被执行)。输出的顺序取决于 CPU 调度程序如何调度进程,这是您无法预测的。


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
2008
upstart
的进程 ID(= 在这里处理僵尸进程)
6672
main
函数
的进程ID
6673
第一个子进程,它的父母是主要的:
6672

6674
第二个孩子进程,
2008
(=暴发户)成为它的父母

虽然我不确定,但我猜你在主进程中有 2 个子进程,因此总共有 3 。由于您没有检查

-1
调用
fork(2)
的失败,因此在其他运行代码的人身上可能会有所不同。


注意
由于您没有

wait(2)
为您的孩子和主要出口未终止他们,所以
upstart(8)
负责终止他们。

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

fork(2)

© www.soinside.com 2019 - 2024. All rights reserved.