为什么信号暂停会导致程序永远睡眠?

APUE书中说:如果信号在sig_int_flag测试之后但在暂停调用之前发生,则该过程可以永远进入睡眠状态.

我不知道为什么,有人可以告诉我吗?
非常感谢.

int sig_int();                 /* my signal handling function */
int sig_int_flag;              /* set nonzero when signal occurs */

int main() {
    signal(SIGINT, sig_int)    /* establish handler */
    .
    .
    .
    while (sig_int_flag == 0)
        pause();               /* go to sleep, waiting for signal */
}

int sig_int() {
    signal(SIGINT, sig_int);   /* reestablish handler for next time */
    sig_int_flag = 1;          /* set flag for main loop to examine */
}

最佳答案 如果在您描述的精确时间发出中断信号:

>该标志已被检查为false:进入循环
>信号重置自己,将标志设置为1,但为时已晚(测试已完成)
>因为已经输入循环,所以调用pause()并且程序等待

也就是说,如果再次触发CTRL C / SIGINT,您可以退出循环,因此它不是那么重要,因为该信号可以手动发出.

如果要检查该行为,我建议您添加一个sleep语句:

while (sig_int_flag == 0)
{
     printf("Hit CTRL+C in the next 10 seconds to trigger the bug\n");
     sleep(10);
     pause();               /* go to sleep, waiting for signal */
}

解决方法是删除pause()语句并将其替换为轮询循环:

while (sig_int_flag == 0)
{
     sleep(1);
}

如果SIGINT出现在循环中的任何地方,包括while和sleep之间,则可能发生的最糟糕的事情是程序在注意到标志被设置之前等待1秒,然后它退出循环,而另一个,更多似乎是睡眠呼叫中断,并且循环立即退出,所以当设置信号时,如果我们只期望SIGINT,那么它和暂停调用之间几乎没有明显的区别.

点赞