信号阻塞问题

来源:互联网 发布:树莓派3 有线网络配置 编辑:程序博客网 时间:2024/06/07 03:47

  今天在看《深入理解计算机系统》第8章的内容时,对于图8-31的代码有一些疑惑.

  为什么会是阻塞第二个信号,自己在ubuntu14.04(内核为linux3.13.0-24)上敲了一遍代码

 

#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/types.h>#include<sys/wait.h>#include<signal.h>#include<unistd.h>void handler1(int sig){pid_t pid;pid = waitpid(-1 , NULL , 0);printf("Handler reaped child %d \n" , pid);sleep(2);return;}int main(){int i , n;if ( signal(SIGCHLD , handler1) == SIG_ERR ){printf("signal error\n");}for(i = 0; i < 3; ++i){if (fork() == 0){printf("Hello from child %d\n" , getpid());sleep(1);exit(0);}}printf("Father love you!\n");while(1);exit(0);}
 最后的运行结果为

yk@yk-desktop:~/Public$ gcc -o fork1 hello.cyk@yk-desktop:~/Public$ ./fork1 Father love you!Hello from child 3225Hello from child 3226Hello from child 3227Handler reaped child 3225 Handler reaped child 3226 

证明了书上的结果是不正确的

我的理解为hadler在处理第一个信号时应该是将第二个信号放在待处理列表,当第三个信号到来时,由于不能同时将多个同类型信号放在待处理列表,从而忽略第三个信号。

而将handler函数优化之后产生了一个很奇妙的现象//改为while循环处理信号

void handler1(int sig){pid_t pid;while((pid = waitpid(-1 , NULL , 0)) > 0)printf("Handler reaped child %d \n" , pid);sleep(2);return;}
由于父进程与子进程的处理顺序不一致,几次的运行结果都不同

yk@yk-desktop:~/Public$ gcc -o fork1 hello.cyk@yk-desktop:~/Public$ ./fork1 Father love you!Hello from child 3530Hello from child 3528Hello from child 3529Handler reaped child 3530 Handler reaped child 3528 Handler reaped child 3529 ^Cyk@yk-desktop:~/Public$ gcc -o fork1 hello.cyk@yk-desktop:~/Public$ ./fork1 Hello from child 3538Father love you!Hello from child 3539Hello from child 3540Handler reaped child 3538 Handler reaped child 3539 Handler reaped child 3540 ^Cyk@yk-desktop:~/Public$ gcc -o fork1 hello.cyk@yk-desktop:~/Public$ ./fork1 Hello from child 3551Father love you!Hello from child 3553Hello from child 3552Handler reaped child 3551 Handler reaped child 3553 Handler reaped child 3552

真有意思~

0 0