Chinaunix首页 | 论坛 | 博客
  • 博客访问: 76513
  • 博文数量: 35
  • 博客积分: 131
  • 博客等级: 入伍新兵
  • 技术积分: 150
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-11 22:57
文章分类

全部博文(35)

文章存档

2016年(15)

2013年(1)

2012年(6)

2011年(13)

我的朋友

分类:

2011-11-15 16:36:56

原文地址:僵死进程的避免 作者:wcw

昨天写了个简单的服务器程序http-serv,每次http-serv接受(accept)到一个请求时,都会创建一个新的子进程来响应该请求。于是每个子进程的退出,便需要处理,否则就是会出现僵死进程。
刚开始我是这样处理的:

static void
sig_child()
{
    waitpid(-1, NULL, 0);
}
[...]
signal(SIGCHLD, sig_child);

即用sig_child来处理SIGCHLD信号(进程退出时,父进程会收到该信号)。
刚开始这样并没问题,后来用了apach自带的ab进行了压力测试,就出现了僵死进程了。
想了好久,看了很多资料,最后发现sig_child这个函数有问题。这个函数的作用是每当有一个进程退出时,便会调用一次sig_child,sig_child便会调用waitpid处理一个已退出的子进程。但是假如程序正在sig_child里面,这时又有另外一个子进程退出了,这时该怎么处理呢?处理的方法应该是不会有另外一个sig_child响应,于是这时便有2个子进程退出了,但是sig_child只能处理一个,于是便有一个退出的子进程成了僵死进程了。

于是把sig_child改成:

static void
sig_child()
{
    while (waitpid(-1, NULL, 0) > 0);
}

这样假如程序正在sig_child里面,这时又有另外n个子进程退出了,由于用了while,于是sig_child便会将所以退出的子进程“一网打尽”。

这是一种处理僵死进程的方法,另外还有2种:
signal(SIGCHLD, SIG_IGN);
忽略SIGCHLD信号,父进程不需要处理,直接把退出的子进程推给init进程处理。

struct sigaction    sa;
sa.sa_handler = SIG_IGN;
sa.sa_flags = SA_NOCLDWAIT;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGCHLD, &sa, NULL) < 0) {
    exit(-1);
}
第3种的机制跟第2种的机制是一样的,只是调用的接口不同,这里不再累诉。
阅读(586) | 评论(0) | 转发(0) |
0

上一篇:何为僵死进程

下一篇:用C++模块实现栈

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