sigprocmask() 问题
下面的代码来自W. Richard Stevens的unix环境中的高级编程一书
,关于这本代码的书说:
“如果信号在进程被阻塞时发送到进程,则信号传递将被推迟,直到信号被解除阻塞为止。对于应用程序来说,这看起来就像信号发生在解除阻塞和暂停之间(取决于如果发生这种情况,或者信号确实发生在解除阻塞和暂停之间,那么在这个时间窗口中出现的任何信号都会丢失,因为我们可能看不到信号。再次发出信号,在这种情况下暂停将无限期地阻塞。这是早期不可靠信号的另一个问题。”
并且它建议在重置信号掩码之前使用 sigsuspend() 而不是暂停(),因为它会重置信号掩码并在单个原子操作中使进程进入睡眠状态。但我不希望我的进程等到走出关键区域后发出信号。 那么这个问题也适用于我的情况吗?如果是的话,我应该使用什么来在使用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 */
The code below is from the book Advanced programming in unix environment, W. Richard Stevens
And about this code book says;
"If the signal is sent to the process while it is blocked, the signal delivery will be deferred until the signal is unblocked. To the application, this can look as if the signal occurs between the unblocking and the pause (depending on how the kernel implements signals). If this happens, or if the signal does occur between the unblocking and the pause, we have a problem. Any occurrence of the signal in this window of time is lost in the sense that we might not see the signal again, in which case the pause will block indefinitely. This is another problem with the earlier unreliable signals."
And it recommands to use sigsuspend()
before resetting signal mask instead of pause()
since it resets the signal mask and put the process to sleep in a single atomic operation. But I don't want my process wait until signal came after stepping out of critical region. So is this problem valid for my case too? If so what should i use not to lose signal while reseting signal mask with 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 */
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用 sigsuspend 是为了避免 sigprocmask 和暂停之间的过程。如果您不需要在收到信号之前停止线程,则 sigsuspend 无法为您做任何事情。您没有提供足够的信息来了解您的环境中是否存在其他问题来源。
sigsuspend is used in order to avoid a course between sigprocmask and pause. If you don't need to halt your thread until a signal is received, there is nothing sigsuspend can do for you. You don't give enough information to know if there are other sources of trouble in your context or not.