文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>僵死进程的避免

僵死进程的避免

时间:2009-03-11  来源: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种的机制是一样的,只是调用的接口不同,这里不再累诉。
相关阅读 更多 +
排行榜 更多 +
特技摩托挑战(wheelie challenge)

特技摩托挑战(wheelie challenge)

赛车竞速 下载
创造世界游戏

创造世界游戏

冒险解谜 下载
终极躲避球

终极躲避球

休闲益智 下载