- 论坛徽章:
- 0
|
向大家请教一个关于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???
哪位能给我解释一下原因?多谢了!
顺便说一下,子进程所执行的程序运行时间非常短,所以一定会出现“子进程还没有全部生成,就已经有子进程结束了”的情况。 |
|