根据this paragraph,以下问题:
/* usr_interrupt is set by the signal handler. */
if (!usr_interrupt)
pause ();
/* Do work once the signal arrives. */
...
应该使用sigsuspend
代替。
但我仍然看不出pause
的问题以及sigsuspend
如何解决问题,
任何人都可以更详细地解释一下?
答案 0 :(得分:3)
让我们来看看在您调用usr_interrupt
之后检查pause
但是之前信号到达时会发生什么:
main thread signal handler ----------- -------------- if (!usr_interrupt) // this is true // signal kicks up handler usr_interrupt = 1; // handler finishes pause(); // will wait for signal
在这种情况下,您可以看到错过了信号。非常重要的是,如果没有其他信号传入,因为您的程序永远不会采取行动。这就是众所周知的竞争条件。现在让我们看看sigsuspend
:
main thread signal handler ----------- -------------- // set up to delay signal. sigemptyset (&mask); sigaddset (&mask, SIGUSR1); // this will delay (block) signal. // possibly do this first if USR1 // may be blocked already (check!): // sigprocmask (SIG_UNBLOCK, &mask, &old); sigprocmask (SIG_BLOCK, &mask, &old); if (!usr_interrupt) // signal arrives, delayed. // unblock signal/wait (atomically). sigsuspend (&old); // delayed handler start. usr_interrupt = 1; // handler finishes. // sigsuspend returns, clean up. sigprocmask (SIG_UNBLOCK, &mask, NULL);
在这种情况下,没有竞争条件,因为信号被延迟,直到主线程准备就绪。
答案 1 :(得分:0)
这是一种典型的竞争条件。
Main | Signal handler --------------------|----------------------- // at this point, | // no signal has | // arrived, so we | // enter the if | | if (!usr_interrupt) | | {signal arrives...} | usr_interrupt = 1; | {...handler finishes} pause(); | | // uh-oh, we missed | // the signal! |
现在pause()
在下一个信号到来之前不会被解除阻塞(根据程序可能永远不会发生)。