Давайте рассмотрим, что происходит, когда сигнал приходит после того, как вы проверили 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);
В этом случае условия гонки отсутствуют, поскольку сигнал задерживается до тех пор, пока основной поток не будет готов к нему.