了解waitpid如何处理信号



考虑以下伪C代码:

static int G = 0;
void alrm_handler(int signo) {
G = 1;
}
void son() {
struct sched_param param;
param.sched_priority = 50;
sched_setscheduler(getpid(),SCHED_FIFO, &param);
kill(getppid(), SIG_ALRM);
sched_yield();
printf("An");
while(1);
exit(0);
}
int main() {
signal(SIG_ALRM, alrm_handler);
int son_pid = fork();
if(son_pid==0)
son();
waitpid(son_pid);
printf("Bn");
return 0;
}

它来自操作系统的一次考试。问题如下:

In multi cores CPU what would be printed?

答案是我们不能知道,因为它可能是A然后是B,或者B然后是A。我不明白为什么。如果父级正在用waitpid等待子级,并且子级发送信号SIG_ALRM,为父级调用alrm_handler函数,则父级将完成该函数的执行,然后返回等待子级直到其完成运行,否?所以它应该是A,然后是B

根据POSIX,在调用signal设置的信号处理程序后,是否重新启动系统调用是未定义的。

  • System V和Linuxsignal系统调用不会重新启动系统调用
  • BSD和默认的GLibc会重新启动系统调用

如果使用System Vsignal,则waitpid可以在发送信号后立即返回,从而允许按任何顺序打印字母。如果标准输出是管道或常规文件,则只有B将被输出,因为子级处于无限循环中

在BSDsignal中,由于子级中的无限循环,waitpid不会返回,因此只打印A。如果标准输出是管道或常规文件,则不会输出任何内容。

最新更新