在《 CSAPP 》中有一个简单的 signal 示例程序。我在 Ubuntu 里编译运行相同的代码,得到的结果和书上给出的结果不一样,并且就是在最关键的一个地方不一样:信号不排队。
而我在自己的机器上编译运行结果:
按照书里面的说法,Handler reaped child 这一项应该只出现两次。
#include "csapp.h"
/* $begin signal1 */
/* WARNING: This code is buggy! */
void handler1(int sig)
{
int olderrno = errno;
if ((waitpid(-1, NULL, 0)) < 0)
sio_error("waitpid error");
Sio_puts("Handler reaped child\n");
Sleep(1);
errno = olderrno;
}
int main()
{
int i, n;
char buf[MAXBUF];
if (signal(SIGCHLD, handler1) == SIG_ERR)
unix_error("signal error");
/* Parent creates children */
for (i = 0; i < 3; i++) {
if (Fork() == 0) {
printf("Hello from child %d\n", (int)getpid());
exit(0);
}
}
/* Parent waits for terminal input and then processes it */
if ((n = read(STDIN_FILENO, buf, sizeof(buf))) < 0)
unix_error("read");
printf("Parent processing input\n");
while (1)
;
exit(0);
}
/* $end signal1 */
1
redsonic 2018-08-06 00:15:27 +08:00 1
内核中的信号处理和进程调度有关联性,一般都是计时上的问题,我试了两台空闲的都和书上的一样,打印两次。然后生成子进程的时候延迟错开一下就打印三次了,exit 的时候不容易撞到。不必纠结,也许你系统繁忙 /空闲的时候结果会不一样,明白道理就行了。
/* Parent creates children */ for (i = 0; i < 3; i++) { usleep(100) if (Fork() == 0) { |
2
manifold 2018-08-06 02:19:35 +08:00 via Android
这个本身就取决于进程调度(因为 signal 是在陷入内核是 handle 的)。。所以理论上可以出现各种情况。因此要用 waitpid 来回收 zombie processes
|
3
ryd994 2018-08-06 02:21:44 +08:00 via Android
你是不是在虚拟机里,而且是单核虚拟机?
|
5
ryd994 2018-08-06 06:50:09 +08:00 via Android
|