APUE书中说:如果信号发生在sig_int_flag
的测试之后,但在调用pause
之前,该过程可能会永远进入睡眠状态。
我不知道为什么,有人可以告诉我吗? 非常感谢。
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 */
}
答案 0 :(得分:1)
如果在您描述的确切时间发出中断信号:
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秒,然后它退出循环,另一个更合理的情况是sleep
调用被中断,并且循环立即退出,所以当设置信号时,它和它之间几乎没有明显的区别。如果我们只期望pause
,则SIGINT
来电。
答案 1 :(得分:0)
问题已经回答。但是,其他答案可以巩固这一想法。
while (sig_int_flag == 0) {
<----- think it signal is caught here before pause btw while and pause()
pause(); /* go to sleep, waiting for signal */
}
被捕获后,信号处理程序将运行。完成任务后,返回到捕获信号的位置,在这种情况下为main()
。因此,关键点是pause()
并调用了pause()
。它再次等待SIGINT
赶上。为了举例说明,我等效地添加了sleep(5)
以捕获先前的pause()
。
因此,我们通常需要第二种情况。为了始终实现它,上述代码块必须是 atomic 。这就是sigsuspend()
更好并且应该使用的原因。
如果您想体验容易犯错的情况,
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
volatile sig_atomic_t sig_int_flag = 0; /* set nonzero when signal occurs */
char const * handlerMsg = "in handler\n";
int handlerMsgLen;
void sig_int(int s) {
signal(SIGINT, sig_int); /* reestablish handler for next time */
sig_int_flag = 1; /* set flag for main loop to examine */
write(2, handlerMsg, handlerMsgLen);
}
void mySleep() {
for (int i = 0; i < 5; ++i) {
sleep(1);
fprintf(stderr, "%d ", i + 1);
}
}
int main() {
handlerMsgLen = strlen(handlerMsg);
signal(SIGINT, sig_int); /* establish handler */
while (sig_int_flag == 0) {
mySleep();
pause(); /* go to sleep, waiting for signal */
}
}