免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1458 | 回复: 0
打印 上一主题 下一主题

请教一个关于wait(),waitpid()使用的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-08-21 17:38 |只看该作者 |倒序浏览
向大家请教一个关于wait(), waitpid()的问题。

我想写个小程序,它的功能是这样的:
生成多个子进程,让它们执行相同的操作;然后父进程等待所有子进程返回,并接受它们的返回状态。

其实是个很简单的进程控制问题。我的基本过程思路是这样:
(1)用sigaction()函数设定SIGCHLD的处理程序sigchld_handler();
(2)用fork()函数循环生成子进程,并执行execl();
我的代码如下:


pid_t   ChildPorcessId[MultProcessQuantity];

void
sigchld_handler(int sig_no)
{
        pid_t   ChildPid;
        int     i;

        /* 方法一 */
        for (i=0; i<MultProcessQuantity; i++) {
                if (ChildPorcessId[i] != 0) {
                        if ((ChildPid = waitpid(ChildPorcessId[i],(int*)(&ChildStatus), WNOHANG)) != 0) {
                                ChildPorcessId[i] = 0;
                                /* To do something here ...*/
                        }
                }
        }

/*  方法二
        while((ChildPid = wait((int*)(&ChildStatus))) != -1) {
        }
*/

}


int
main (int argc, char *argv[])
{
        struct sigaction        SigChldAction;
        sigset_t                SigChldSet;
        char                    ProgName[128];          /* 要运行的程序名称 */
        char                    ProgPathName[1024];     /* 要运行的程序路径名称 */
        int                     MultProcessQuantity;    /* 并行的进程个数 */
        int                     i;
        pid_t                   ChildPid;


        memset(ChildPorcessId, 0, sizeof(ChildPorcessId));

        /* Intialize 'ProgName','ProgPathName' */
        /*
           ...
        */

        /* To catch SIGCHLD */
        if (sigemptyset(&SigChldSet)) {
                return -1;
        }
        if (sigaddset(&SigChldSet, SIGCHLD)) {
                return -1;
        }
        SigChldAction.sa_handler = sigchld_handler;
        SigChldAction.sa_flags = 0;
        sigaction(SIGCHLD, &SigChldAction, NULL);


        /* Create child processes and exec() */
        for (i=0; i<MultProcessQuantity; i++) {
                ChildPid = fork();

                if (ChildPid < 0) {
                        return  -1;
                } else if (ChildPid == 0) {
                        execl(ProgPathName, ProgName, (char *)0);
                } else {
                        ChildPorcessId[i] = ChildPid;
                }
        }

        return  0;
}


但是我在实际中遇到了一点小问题,主要是在回收子进程状态时。
我发现如果我在sigchld_handler()函数中使用方法一,我不能完全回收所有子进程的状态,总是会漏掉几个(我是通过打印跟踪信息知道的)。如果用方法二,就可以回收到所有子进程的状态。
Why???
哪位能给我解释一下原因?多谢了!

顺便说一下,子进程所执行的程序运行时间非常短,所以一定会出现“子进程还没有全部生成,就已经有子进程结束了”的情况。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP