【发布时间】:2011-04-16 18:27:02
【问题描述】:
以下代码来自unix 环境中的高级编程一书,W. Richard Stevens
关于这本密码书说;
“如果信号在被阻塞时被发送到进程,信号传递将被推迟到信号被解除阻塞。对于应用程序来说,这看起来好像信号发生在解除阻塞和暂停之间(取决于内核如何实现信号)。如果发生这种情况,或者如果信号确实发生在解除阻塞和暂停之间,我们就有问题了。在这个时间窗口中任何出现的信号都会丢失,因为我们可能看不到再次发出信号,这种情况下暂停将无限期阻塞。这是早期不可靠信号的另一个问题。”
它建议在重置信号掩码之前使用sigsuspend() 而不是pause(),因为它会重置信号掩码并使进程在单个原子操作中进入睡眠状态。但我不希望我的过程等到退出关键区域后出现信号。 那么这个问题对我的情况也有效吗?如果是这样,在使用sigprocmask() 重置信号掩码时我应该使用什么来不丢失信号?
sigset_t newmask, oldmask;
sigemptyset(&newmask);
sigaddset(&newmask, SIGINT);
/* block SIGINT and save current signal mask */
if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
err_sys("SIG_BLOCK error");
/* critical region of code */
/* reset signal mask, which unblocks SIGINT */
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
err_sys("SIG_SETMASK error");
/* window is open */
pause(); /* wait for signal to occur */
/* continue processing */
【问题讨论】:
-
你还没有真正弄清楚你的问题是什么。你有一个关键的代码区域吗?你的情况是什么?
-
我的代码与上面的代码类似,没有 pause() 但其他我自己的功能。在两个 sigprocmask() 调用之间是我的关键区域,如上面的代码,但在我的情况下,上面的所有代码都在 while(1) 循环中。所以我希望我的信号处理程序在程序执行超出临界区并且如果信号(它是一个 SIGALRM)被传递时工作。
-
您可以在调用 sigprocmask() 解锁信号之前使用 sigpending() 来查找挂起的信号,但这似乎有点矫枉过正。