What's the problem of pause() at all?

我的未来我决定 提交于 2021-02-07 19:14:56

问题


According to this paragraph ,the following has problem:

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

And should use sigsuspend instead.

But I still don't see what the problem is with pause and how sigsuspend solves it,

anyone can explain in more details?


回答1:


Let's examine what happens when a signal arrives after you've checked usr_interrupt but before you call 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

You can see in that case that you've missed the signal. Extremely important if there is no further signal incoming since your program will never action it. That's what's known as a race condition. Now let's see what happens with 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);

In this case, there is no race condition since the signal is delayed until the main thread is ready for it.




回答2:


This is a classic race condition.

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!      |

Now the pause() won't get unblocked until the next signal arrives (which may never happen depending on the program).



来源:https://stackoverflow.com/questions/6328055/whats-the-problem-of-pause-at-all

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!