什么是pause()的问题呢?

时间:2011-06-13 08:16:07

标签: signals

根据this paragraph,以下问题:

 /* usr_interrupt is set by the signal handler.  */
 if (!usr_interrupt)
   pause ();

 /* Do work once the signal arrives.  */
 ...

应该使用sigsuspend代替。

但我仍然看不出pause的问题以及sigsuspend如何解决问题,

任何人都可以更详细地解释一下?

2 个答案:

答案 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()下一个信号到来之前不会被解除阻塞(根据程序可能永远不会发生)。