网络编程中wait与waitpid的区别

来源:互联网 发布:先入为主知乎 编辑:程序博客网 时间:2024/04/30 07:11

问题:

一个unp中第五章的例子:有5个客户端几乎同时向服务器发送终止连接,这时在服务器端将几乎同时产生SIGCHILD信号,然而信号在内核中是不排队的,信号处理函数只执行一次(我的理解是5个信号几乎同时到达,当第一个信号被处理时,其他4个信号是未决的,当信号处理函数处理完第一个到达的信号后,由于没有产生信号,信号处理函数将不会被再次调用)。那么在目前情况下,父进程怎样才能捕获到所有的子进程的退出状态呢?

分析:

在SIGCHLD的handler中添加如下代码显然不行:

void
sig_chld(int signo)
{
pid_t pid;
int stat;

pid = wait(&stat);
printf("child %d terminated\n", pid);
return;
}

因为使用wait时,它只等到第一个SIGCHLD到达的子进程,之后就如上所示return了。在信号处理函数只能执行一次的前提下,其他4个SIGCHLD信号就没有被处理。

而如果在handler中使用如下的方式就可以:

void
sig_chld(int signo)
{
pid_t pid;
int stat;

while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0)
printf("child %d terminated\n", pid);
return;
}

原因分析如下:在while循环中使用waitpid的非阻塞模式(WNOHANG),当第一个信号到达时,printf然后回到while继续waitpid,接着第二个信号到达,依次处理,直到这5个信号都被处理完之后,根据WNOHANG常量的说明“The waitpid function will not block if a child specified by pid is not immediately available. In this case, the return value is 0. ”(见APUE2中8.6节),所以waitpid将返回0,跳出while循环,这样子进程的终止状态都被捕获到了,父进程继续做它的事。

总结:

wait与waitpid的主要区别:

(1)waitpid能够等指定pid的子进程;而wait只能等第一个到达的子进程。

(2)waitpid通过指定WNOHANG可以不阻塞,没有可用的子进程就立即返回0;而wait要求父进程一直阻塞。

上面这两点其实就是waitpid比wait多了1、3两个参数。

补充:

查看源码,wait就是包装过的waitpid,include/unistd.h

static inline pid_t wait(int * wait_stat)
{
return waitpid(-1,wait_stat,0);
}


来自:http://hi.baidu.com/penzo/blog/item/47b7b538b583cc2f97ddd8fd.html

原创粉丝点击