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

8 篇文章 0 订阅

原文地址:

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  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值