根据本段,以下有问题:
/* usr_interrupt is set by the signal handler. */
if (!usr_interrupt)
pause ();
/* Do work once the signal arrives. */
...
Run Code Online (Sandbox Code Playgroud)
并且应该sigsuspend改用。
但我还是不明白问题出在哪里pause以及如何sigsuspend解决,
谁能更详细地解释一下?
让我们检查在您检查之后usr_interrupt但在您调用之前信号到达时会发生什么pause:
主线程信号处理程序
----------- --------------
如果(!usr_interrupt)
// 这是真的 // 信号启动处理程序
usr_interrupt = 1;
// 处理程序完成
暂停();
// 将等待信号
在这种情况下,您可以看到您错过了信号。如果没有进一步的信号传入,这一点非常重要,因为您的程序永远不会对其进行操作。这就是所谓的竞态条件。现在让我们看看会发生什么sigsuspend:
主线程信号处理程序
----------- --------------
// 设置延迟信号。
sigemptyset (&mask);
sigaddset (&mask, SIGUSR1);
// 这将延迟(阻塞)信号。
// 如果 USR1,可能首先执行此操作
// 可能已经被阻止(检查!):
// sigprocmask (SIG_UNBLOCK, &mask, &old);
sigprocmask (SIG_BLOCK, &mask, &old);
如果(!usr_interrupt)
// 信号到达,延迟。
// 解除阻塞信号/等待(原子地)。
sigsuspend (&old);
// 延迟处理程序启动。
usr_interrupt = 1;
// 处理程序完成。
// sigsuspend 返回,清理。
sigprocmask (SIG_UNBLOCK, &mask, NULL);
在这种情况下,没有竞争条件,因为信号被延迟到主线程准备好。