分享

[保留] 关于SIGCHLD的不排队,丢弃的问题 - ChinaUnix.net

 omcc 2011-01-07

看unix网络编程第一卷的时候,碰到书上这样一个例子: 
一个并发服务器, 每一个客户端连接服务器就fork一个子进程.书上讲到当同时有n多个客户端断开连接时, 
服务器端同时有n多个子进程终止, 这时候内核同时向父进程发送n多个sigchld信号.它的sigchld信号处理 
函数如下: 
void sig_chld(int signo) 

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


我的问题是:既然sigchld是不可靠的信号,进程就不可能对sigchld进行排队, 直接丢弃了sigchld信号(当进程注册信号的时候,发现已有sigchld注册进未决信号, 因为内核同时发送多个sigchld).请问大家上面的代码是如何保证不产生僵尸进程的.谢谢!



 xltao 回复于:2006-09-15 15:28:58

高人指点啊


 linternt 回复于:2006-09-15 16:03:58

用消息队列吧,子进程退出前把自已的PID写进队列 
然后父进程去读,不过pid = waitpid(-1, &stat, 0); 
让父进程阻塞在调用这块,不过如果你想让waitpid快带返回也行, 如果没接到子进程退出信号,你可以把这个PID再写进去,然后继续读,直到接到SIGCHLD为止。 

以前在项目中遇到过此问题,大量的并发进程往往造成很多的僵死进程,以至于程序无法响应,当时被这个问题弄得很头痛,直到想到这个方法以后才有效的解决了上述问题。 

为方法就等于实现了一个对SIGCHLD的排队机制。我一直在大型的项目中用这个,很不错。


 思一克 回复于:2006-09-15 16:08:45

你能给出一简短的例子引起你说的那个问题的程序?


 susesuse 回复于:2006-09-15 16:36:42

我的看法,不一定对啊,呵呵.先看看下面的程序. 


#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>

void sig_child(int signo)
{ pid_t pid;
int stat;
while( (pid = waitpid(-1,&stat,WNOHANG)) > 0)
{
printf("child %d exit\n",pid);
sleep(5);//这应该导致信号丢失吧?
}
return;
}

void child_func()
{
return;
}

int main()
{
pid_t pid;
int i = 0;

signal(SIGCHLD,sig_child);
for(;i < 5;i ++)
{
if( (pid = fork()) == 0)
{
child_func();
printf("child function finished\n");
exit(0);
}
else if(pid > 0)
{
continue;
}
else
{
printf("fork failed\n");
exit(1);
}
}
return 0;




linux:~/test # gcc -o waitpid waitpid.c 
linux:~/test # ./waitpid 
child function finished 
child 7449 exit 
child function finished 
child 7450 exit 
child function finished 
child 7454 exit 
child function finished 
child 7455 exit 
child function finished 
child 7459 exit 

对于SIGCHILD信号(属于不可靠信号,不支持信号排队.),按理说应该有信号丢失,可为什么还是输出5次呢?这实际上没有把握清楚waitpid(-1,&stat,WNOHANG)函数的作用.它是用来用来检测进程是否已结束并回收僵尸进程的,在这个程序里信号确实会丢失的.但waitpid函数不是由SIGCHILD信号驱动的.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多