2017-09-24 42 views
1

我试图确定的处理多少总数有以下代码:计算在叉的过程总数()码

#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是分叉系统调用的数量。我很困惑,因为这个示例涉及if/else条件语句。

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

谢谢大家。

+1

将printf更改为显示'printf(“i =%d,pid =%d \ n”,i,getpid());'你将自己得到答案。或者,更好的方法是打印'getppid()'的结果,您就可以构建整个流程层次结构。 –

回答

1

关注:在if()报表进行评估true即使fork()没有赢得成功,因为在这种情况下,它会返回一个负数是从0true不同。

你有3个过程

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

因此,子流程在进入第二个if语句之前执行一个分支,然后被消除。叉子产生一个孩子的副本(现在成为父母),即一个孙子。你现在有3个进程。

儿童评估else if条件true并会递减i而孙评估false,并且将增加i。根据我的说法,如果你试图执行你的程序,你将只能得到3个输出(执行3个printf())。输出的顺序取决于CPU调度程序如何调度进程,这是您无法预测的。

+0

嗨@Neb这个答案让我更容易理解。我想知道它的可视化效果如何?它只是:父母 - >孩子 - >孩子的孩子(孙子)?以下是我对可视化的看法:http://oi65.tinypic.com/ofztrr.jpg – Derek

+1

@Derek:确切地说。父执行流程进入第一个'i ++',所以它永远不会执行第二个'fork()'。它的孩子会这样做,并会产生孙子。你的图是正确的。既然我帮了你,你能帮我接受我的答案吗? – Neb

+0

嗨@Neb最后一个问题,孙子怎么评价为假?它不应该是真的,因为else语句意味着fork()== 0?哪个评估对孩子是真实的?现在接受你的答案:)谢谢。 – Derek

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是进程ID upstart(=照顾zombi这里的电子处理)
6672main功能
6673的进程ID为第一子过程及其父母是主要:6672
6674第二子过程和2008(=暴发户)成为其父母

虽然我不知道,但我猜你有子进程沿着主,因此共3个。由于您没有检查-1调用fork(2)的失败,所以在运行代码的其他人可能会有所不同。


注意
因为你为你的孩子和主要出口不wait(2)不终止它们,upstart(8)需要终止他们的照顾。

注2:
以这种方式,则不应使用fork(2)