关于linux环境下信号SIGCHLD的排队机制

下面是关于在SIGCHLD的一遍网上的摘要,但是在linux中是不许要这样做的。
signal(SIGCHLD,SIG_IGN); 就可以了,我已经子啊ubuntu12.04上面做过了测试!
  1 #include <sys/types.h>
  2 #include <unistd.h>
  3 #include<stdio.h>
  4 #include<stdlib.h>
  5 #include<signal.h>
  6 int main()
  7 {
  8         signal(SIGCHLD,SIG_IGN);
  9         pid_t  tid= fork();
10         if(tid == 0){
11
12
13           printf("child process %d\n",getpid());
14           exit(0);
15
16          }else if(tid >0){
17
18
19           printf("parent process %d\n",getpid());
20           while(1==1)
21                 {
22
23
24                 }
25            }
26
27 }


result:
不使用signal(SIGCHLD,SIG_IGN);
aircoder@aircoder-ThinkPad-T430:~/c/test$ ps aux | grep aaa | grep -v grep
aircoder  3469 98.2  0.0   4152   348 pts/0    R+   23:20   0:10 ./aaa
aircoder  3470  0.0  0.0      0     0 pts/0    Z+   23:20   0:00 [aaa] <defunct>
使用signal(SIGCHLD,SIG_IGN);
aircoder@aircoder-ThinkPad-T430:~/c/test$ ps aux | grep bbb | grep -v grep
aircoder  3482 87.3  0.0   4152   352 pts/0    R+   23:20   0:05 ./bbb
aircoder@aircoder-ThinkPad-T430:~/c/test$


《《网络摘要
一直对这个问题没有深入的思考过。最近由于项目的需要终于弄清了这个问题。
以下文字是抄袭+理解+估计:
在linux系统中,子进程的正常/异常终止都会给父进程发送SIGCHLD的信号,当父进程接收到子进程(第一个)信号进行wait()或waitpid()时,会屏蔽掉下一个的SIGCHLD信号,实际的效果就是在信号处理函数返回前不会重入。
那么当父进程在执行信号处理函数时,又有子进程(第二个)退出,那么信号会被阻塞并等待处理,假如(第三个)又来了,那么它是被抛弃的,后续的都会抛弃。。。
所以说信号是阻塞但不排队的。
如果子进程可能会同时退出,那么父进程需要这样来处理以防止僵尸进程的出现:
pid_t childpid;
while( (childpid = waitpid(-1, NULL, WNOHANG)) > 0)
{
...
}
这样,即使出现子进程同时退出的情况,SIGCHLD的信号被抛弃也没有关系。waitpid会收集所有当前已终止(实际就是处于僵尸状态)的子进程,直到没有这样的进程状态需要收集(返回0)
》》

猜你喜欢

转载自aircoder.iteye.com/blog/1843353
今日推荐