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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With