Chinaunix首页 | 论坛 | 博客
  • 博客访问: 558893
  • 博文数量: 142
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1452
  • 用 户 组: 普通用户
  • 注册时间: 2013-09-12 16:28
文章分类

全部博文(142)

文章存档

2016年(10)

2015年(60)

2014年(72)

我的朋友

分类: LINUX

2014-11-10 16:19:54

wait和waitpid的区别前面有对应的文章介绍了(http://blog.chinaunix.net/uid-16813896-id-4454473.html)。
本文偏向于介绍多服务器子进程的情况下,wait和waitpid的使用。基本程序还是使用TCP回射程序。


       场景: 客户端开启多个连接同时连上服务器

当客户端输入CONTROL + D(即结束键盘输入,类似输入EOF)来结束客户端进程,此时由于客户端与服务器的5个子进程分别建立了5个连接,那么客户端结束的时候,会同时发送5个FIN报文给服务器。

1.服务器使用wait在信号处理函数来捕获信号SIGCHLD。

点击(此处)折叠或打开

  1. void sig_chld(int signo)
  2. {
  3.     int status;
  4.     int pid;
  5.     if(signo == SIGCHLD) {
  6.         pid = wait(&status);
  7.         printf("process %d is exited\n",pid);
  8.     }
  9. }

此时,只要有一个子进程结束,wait函数就退出了,明显这里有5个子进程需要父进程捕获退出状态。但是wait只等待一个。

2.在上面的基础上,很容易想到要循环wait等待所有子进程的退出状态

点击(此处)折叠或打开

  1. void sig_chld(int signo)
  2. {
  3.     int status;
  4.     int pid;
  5.     if(signo == SIGCHLD) {
  6.         while((pid = wait(&status)) > 0)
  7.             printf("process %d is exited\n",pid);
  8.     }
  9. }
循环wait解决了多个子进程同时退出时,父进程处理所有退出状态的问题,但是由于wait本身在有子进程的情况下,一定要阻塞,所以在这种情况下使用wait也不合理。
例如:
      client 1 同时发起了5个请求,client 2 也同时发起了5个请求,server对应产生了10个子进程,此时使得client1退出,发送了SIGCHLD信号,父进程进入信号处理函数,循环处理完client 1的5个子进程,由于client 2上还有5个子进程,所有父进程就被阻塞在了wait函数上,那么此时如果 client3 想连接服务器的话,由于服务器被阻塞着,那么client3 的请求将无法得到处理。

3.考虑到前面的循环wait可以解决部分问题,只是会阻塞仍然有问题,那么显然可以考虑函数waitpid来代替wait,设置WNOHANG,使得在子进程没有结束的情况下,父进程不阻塞。

点击(此处)折叠或打开

  1. void sig_chld(int signo)
  2. {
  3.     int status;
  4.     int pid;
  5.     if(signo == SIGCHLD) {
  6.         while((pid = waitpid(-1,&status),WNOHANG) > 0)
  7.             printf("process %d is exited\n",pid);
  8.     }
  9. }
这个也是一般程序中处理SIGCHLD信号的通用代码了。
阅读(1169) | 评论(0) | 转发(0) |
0

上一篇:raw socket

下一篇:linux ls -al 各项说明

给主人留下些什么吧!~~