如何 fork n 个进程(n > 2)

原文地址:

http://kenby.iteye.com/blog/1165923


讲到fork, 一个经典的例子如下:

if ((pid = fork()) == 0) {

    printf("in child %d\n", getpid());

} else if (pid > 0) {

    printf("in parent\n");

} else {

    perror("fork");

    exit(0);

}

现在, 我要创建5个进程, 每个进程都打印出自己的pid,  写下如下代码:

    #include <stdio.h>  
    #include <stdlib.h>  
      
    #define N_PROCESS 5  
      
    int main()  
    {  
        pid_t pid[N_PROCESS];  
        int i;   
      
        /* create child process */  
        for (i = 0; i < N_PROCESS; i++) {  
            if ((pid[i] = fork()) == 0) {  
                printf("in child %d\n", getpid());  
            } else if (pid[i] > 0) {  
                printf("in parent\n");  
            }  
        }  
      
        return 0;  
    }  

看似没有问题, 编译运行, 结果令人惊讶:

    in parent  
    in parent  
    in parent  
    in parent  
    in parent  
    in child 11799  
    in parent  
    in parent  
    in parent  
    in parent  
    in child 11799  
    in parent  
    in parent  
    in parent  
    in child 11807  
    in parent  
    in parent  
    in parent  
    in child 11803  
    in parent  
    in parent  
    in parent  
    in parent  
    in parent  
    in child 11805  
    in child 11799  
    in parent  
    in child 11804  
    in parent  
    in parent  
    in child 11799  
    in parent  
    in parent  
    in child 11806  
    in child 11808  
    in parent  
    in parent  
    in parent  
    in child 11803  
    in child 11809  
    in parent  
    in parent  
    in child 11802  
    in parent  
    in parent  
    in child 11799  
    in child 11801  
    in parent  
    in parent  
    in parent  
    in child 11799  
    in parent  
    in child 11804  
    in parent  
    in child 11811  
    in child 11799  
    in child 11801  
    in parent  
    in child 11815  
    in parent  
    in parent  
    in parent  
    in child 11802  
    in child 11812  
    in parent  
    in child 11799  
    in child 11801  
    in child 11813  
    in parent  
    in parent  
    in parent  
    in child 11800  
    in parent  
    in parent  
    in parent  
    in child 11799  
    in parent  
    in child 11804  
    in child 11810  
    in child 11817  
    in parent  
    in parent  
    in child 11802  
    in child 11812  
    in child 11819  
    in child 11799  
    in child 11801  
    in parent  
    in parent  
    in child 11816  
    in parent  
    in parent  
    in child 11802  
    in parent  
    in child 11814  
    in child 11799  
    in child 11801  
    in parent  
    in child 11815  
    in child 11818  
    in parent  
    in child 11800  
    in parent  
    in child 11822  
    in parent  
    in parent  
    in child 11800  
    in parent  
    in parent  
    in child 11824  
    in child 11799  
    in child 11801  
    in child 11813  
    in parent  
    in child 11823  
    in parent  
    in child 11800  
    in child 11820  
    in parent  
    in parent  
    in parent  
    in child 11800  
    in parent  
    in child 11822  
    in child 11825  
    in child 11799  
    in child 11801  
    in child 11813  
    in child 11821  
    in parent  
    in parent  
    in child 11800  
    in child 11820  
    in parent  
    in child 11828  
    in child 11799  
    in child 11801  
    in child 11813  
    in child 11821  
    in child 11826  
    in parent  
    in child 11800  
    in child 11820  
    in child 11827  
    in child 11829  

数一数, 程序创建了31个子进程! 怪哉, 哪里出问题了呢? 

仔细分析一下, 第一次fork调用时, i = 0, fork完成后, 子进程和父进程拥有相同的存储,

即两者的 i = 0,然后父进程执行parent代码段, 打印 "in parent", 子进程执行child代码

段, 打印自己的pid. 关键是, 到了这里, 子进程没有退出, 处于for循环中, 于是子进程接着

执行 i = 1 时的for循环, 子进程执行fork, 又创建子进程, 这样就产生孙子进程. 按照这种

步骤, 孙子进程又会创建子进程....稍微分析一下, 可以得到递推公式,如果想创建n个子进程,

将执行 2^n - 1次fork调用并产生2^n-1个子进程, 真是子子孙孙无穷尽也...


可见, 问题的关键是, 终止子进程继续执行for循环, 修改代码:

    #include <stdio.h>  
    #include <stdlib.h>  
      
    #define N_PROCESS 5  
      
    int main()  
    {  
        pid_t pid[N_PROCESS];  
        int i;   
      
        /* create child process */  
        for (i = 0; i < N_PROCESS; i++) {  
            if ((pid[i] = fork()) == 0) {  
                printf("in child %d\n", getpid());  
                exit(0);     /* 让子进程退出 */  
            } else if (pid[i] > 0) {  
                printf("in parent\n");  
            }  
        }  
      
        return 0;  
    }  

运行结果如下:
    in parent  
    in child 12037  
    in parent  
    in parent  
    in child 12039  
    in child 12038  
    in parent  
    in child 12040  
    in parent  
    in child 12041  

这次只创建了5个进程, 但parent代码段执行了5次, 不符合我们的要求, 再改:

    #include <stdio.h>  
    #include <stdlib.h>  
      
    #define N_PROCESS 5  
      
    int main()  
    {  
        pid_t pid[N_PROCESS];  
        int i;   
      
        /* create child process */  
        for (i = 0; i < N_PROCESS; i++) {  
            if ((pid[i] = fork()) == 0) {  
                printf("in child %d\n", getpid());  
                exit(0);    /* 让子进程退出 */  
            }   
        }  
      
        printf("in parent\n");  
      
        return 0;  
    }  

运行结果如下:

    in child 12072  
    in parent  
    in child 12074  
    in child 12075  
    in child 12073  
    in child 12076  


发布了28 篇原创文章 · 获赞 9 · 访问量 25万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章