期望输出: done fork
先于got signal
,某一刻出现的done fork
数量大于等于got signal
code:
#include <sys/wait.h>
#include <sys/signal.h>
#include <errno.h>
#include "apue.h"
volatile int counter = 0;
void handler(int sig)
{
char msg[] = "# Got signal from child!\n";
int olderrno = errno; // 保存错误
sigset_t mask_all, mask_pre;
sigfillset(&mask_all);
while ((waitpid(-1, NULL, 0)) > 0) {
sigprocmask(SIG_BLOCK, &mask_all, &mask_pre);
write(STDOUT_FILENO, msg, strlen(msg));
++counter;
sigprocmask(SIG_UNBLOCK, &mask_pre, NULL);
}
if (errno != ECHILD) // 因为跳出上面循环的条件中,预料之中的是找不到运行中的子进程
printf("waitpid error\n");
errno = olderrno;
}
int main()
{
if (signal(SIGCHLD, handler) == SIG_ERR) {
printf("signal error\n");
}
sigset_t mask_one, mask_pre;
sigemptyset(&mask_one);
sigaddset(&mask_one, SIGCHLD);
signal(SIGCHLD, handler);
for (int i = 0; i < 10; ++i) {
sigprocmask(SIG_BLOCK, &mask_one, &mask_pre);
if (fork() == 0) {
// child
char msg[] = "Hello from child\n";
write(STDOUT_FILENO, msg, strlen(msg));
// sleep(1);
exit(0);
}
char msg[] = "# Done fork()\n";
write(STDOUT_FILENO, msg, strlen(msg));
sigprocmask(SIG_SETMASK, &mask_pre, NULL);
sleep(1);
}
printf("Process from parent\n");
sleep(10);
while (1) {
pause();
printf("count: %d\n", counter);
}
exit(0);
}
result:预料之中,先父再子
# Done fork()
Hello from child
# Got signal from child!
# Done fork()
Hello from child
# Got signal from child!
# Done fork()
Hello from child
# Got signal from child!
# Done fork()
Hello from child
# Got signal from child!
# Done fork()
Hello from child
# Got signal from child!
# Done fork()
Hello from child
# Got signal from child!
# Done fork()
Hello from child
# Got signal from child!
# Done fork()
Hello from child
# Got signal from child!
# Done fork()
Hello from child
# Got signal from child!
# Done fork()
Hello from child
# Got signal from child!
Process from parent