关于fork,wait的有关问题

关于fork,wait的问题问题描述很简单,写一个程序接收整数,根据该整数创立若干个进程,sleep一段时间,然后父

关于fork,wait的问题
问题描述很简单,写一个程序接收整数,根据该整数创立若干个进程,sleep一段时间,然后父进程报告每个子进程的退出。
我的代码有个问题我无法理解。先把正确的代码贴出来:

C/C++ code
#include <stdio.h>#include <signal.h>#include <stdlib.h>int wait_pid=0;int main(int args,char *av[]){        //signal(SIGCHLD,report_quit);        if(args==1)        {                printf("You should declare the number of the child process that you want to build!");                 return 1;        }        else        {                int num_p=atoi(av[1]);                int child_pid=1;                 int i=0;                for(i=0;i<num_p;i++)                {                        if(child_pid!=0)                         {                                child_pid=fork();                                 printf("%d :%d \n",getpid(),child_pid);                                if(child_pid==0)                                {                                        sleep(2);                                        exit(17);                                }                                else if(child_pid==-1)                                {                                        perror("fork error!");                                        exit(2);                                }                        }                }                while((wait_pid=wait(NULL))!=-1)                        printf("the child process %d exited!\n",wait_pid);        }        return 0;}

执行结果是:
C/C++ code
11240 :11241 11241 :0 11240 :11242 11242 :0 11240 :11243 11243 :0 11240 :11244 11244 :0 the child process 11241 exited!the child process 11242 exited!the child process 11243 exited!the child process 11244 exited!

而我想利用信号处理的方法:子进程结束时,调用exit时会向父进程发送一个SIGCHLD信号,让父进程捕捉这个信号来报告子进程的结束。代码中加入了一个处理函数:
C/C++ code
#include <stdio.h>#include <signal.h>#include <stdlib.h>void report_quit();int wait_pid=0;int main(int args,char *av[]){        signal(SIGCHLD,report_quit);        if(args==1)        {                printf("You should declare the number of the child process that you want to build!");                 return 1;        }        else        {                int num_p=atoi(av[1]);                int child_pid=1;                 int i=0;                for(i=0;i<num_p;i++)                {                        if(child_pid!=0)                         {                                child_pid=fork();                                 printf("%d :%d \n",getpid(),child_pid);                                if(child_pid==0)                                {                                        sleep(2);                                        exit(17);                                }                                else if(child_pid==-1)                                {                                        perror("fork error!");                                        exit(2);                                }                        }                }                while(1)                        wait_pid=wait(NULL);                       // printf("the child process %d exited!\n",wait_pid);        }        return 0;}void report_quit(){        printf("the child process %d exited.\n",wait_pid);}

但是执行结果如下:
C/C++ code
11266 :11267 11267 :0 11266 :11268 11268 :0 11266 :11269 11269 :0 11266 :11270 11270 :0 the child process 0 exited.the child process 11268 exited.the child process 11268 exited. 


我不明白为什么了。如果您知道,请讲一下,非常感谢。

[解决办法]
信号不排队, 多个子进程同时退出, 信号同时发给父进程,父进程相同的信号不排队, 可能就丢了1个信号, 就是楼主看到只有3个wait结果。

另外。。。 楼主的代码的确是有问题的,竟然不是在信号函数里waitpid,而是main线程wait, 信号处理函数打印wait_pid,这个时序是不确定的, 到底是先收到信号并调用处理函数还是先wait返回呢?

结果楼主倒霉的碰到了信号先被处理,所以打印了你在程序最顶上初始化的那个wait_pid=0.

看代码,楼主还是用了while(1) wait,这不好。 第一段代码根本不可能结束,因为wait是阻塞的。

给楼主写一段标准的代码吧,楼主好好manpage一下,学习一下非阻塞的waitpid的返回值和errno分别代表什么,就能解决你这两个程序的不舒适了。

过会给你贴来,你先自己理解理解这段话把。
[解决办法]
C/C++ code
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <signal.h>#include <errno.h>static volatile sig_atomic_t count = 0;static int nprocs = 0;#define NPROCS 5void sig_handler(int signo) {        pid_t pid;        while (1) {                pid = waitpid(0, NULL, WNOHANG);                if (pid > 0) {                        ++ count;                } else if (pid == 0) {                        return;                } else {                        if (errno == EINTR) {                                continue;                        } else {                                return; // no child left                        }                }        }}int main(int argc, char* const argv[]) {        int i;        sigset_t set, oset;        sigemptyset(&set);        sigaddset(&set, SIGCHLD);        sigprocmask(SIG_BLOCK, &set, &oset);        struct sigaction act;        bzero(&act, sizeof(struct sigaction));        act.sa_handler = sig_handler;        sigaction(SIGCHLD, &act, NULL);        for (i = 0; i < NPROCS; ++ i) {                pid_t pid = fork();                if (pid == -1) {                        break;                } else {                        printf("%s %d\n", pid == 0 ? "child" : "parent", getpid());                        if (pid == 0) {                                sleep(2);                                exit(0);                        }                }        }        nprocs = i;        if (nprocs == 0) { //no proc is created                return -1;        }        while (count != nprocs) {                sigsuspend(&oset);        }        return 0;}
[解决办法]
wait 跟waitpid问题,看下Unix网络编程吧
[解决办法]
探讨

引用:

信号不排队, 多个子进程同时退出, 信号同时发给父进程,父进程相同的信号不排队, 可能就丢了1个信号, 就是楼主看到只有3个wait结果。

另外。。。 楼主的代码的确是有问题的,竟然不是在信号函数里waitpid,而是main线程wait, 信号处理函数打印wait_pid,这个时序是不确定的, 到底是先收到信号并调用处理函数还是先wait返回呢?

结……