关于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网络编程吧
[解决办法]
