В чем проблема pause () вообще? - PullRequest
3 голосов
/ 13 июня 2011

Согласно этому пункту , проблема имеет следующее:

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

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

И вместо него следует использовать sigsuspend.до сих пор не понимаю, в чем проблема с pause и как sigsuspend решает ее,

кто-нибудь может объяснить более подробно?

Ответы [ 2 ]

3 голосов
/ 13 июня 2011

Давайте рассмотрим, что происходит, когда сигнал приходит после того, как вы проверили 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);

В этом случае условия гонки отсутствуют, поскольку сигнал задерживается до тех пор, пока основной поток не будет готов к нему.

0 голосов
/ 13 июня 2011

Это классическое условие гонки.

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() не разблокируется, пока не поступит сигнал next (что может не произойти в зависимости от программы).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...