今天在看《深入理解计算机系统》第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.c
yk@yk-desktop:~/Public$ ./fork1
Father love you!
Hello from child 3225
Hello from child 3226
Hello from child 3227
Handler 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.c
yk@yk-desktop:~/Public$ ./fork1
Father love you!
Hello from child 3530
Hello from child 3528
Hello from child 3529
Handler reaped child 3530
Handler reaped child 3528
Handler reaped child 3529
^C
yk@yk-desktop:~/Public$ gcc -o fork1 hello.c
yk@yk-desktop:~/Public$ ./fork1
Hello from child 3538
Father love you!
Hello from child 3539
Hello from child 3540
Handler reaped child 3538
Handler reaped child 3539
Handler reaped child 3540
^C
yk@yk-desktop:~/Public$ gcc -o fork1 hello.c
yk@yk-desktop:~/Public$ ./fork1
Hello from child 3551
Father love you!
Hello from child 3553
Hello from child 3552
Handler reaped child 3551
Handler reaped child 3553
Handler reaped child 3552
真有意思~