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,那么它和暂停调用之间几乎没有明显的区别.