Sigsuspend эквивалентно атомной серии sigprocmask, pause, sigprocmask? - PullRequest
3 голосов
/ 18 апреля 2019

Я читал главу моего учебника (CS: APP, 3-е изд., Глава 8, стр. 781) о сигналах / ECF для систем Linux x86-64 и наткнулся на это:

Функция sigsuspend временно заменяет текущий заблокированный набор маской, а затем приостанавливает процесс до получения сигнала, действие которого заключается в запуске обработчика или прекращении процесса.Если действие должно быть прекращено, то процесс завершается без возврата из sigsuspend.Если действие заключается в запуске обработчика, то sigsuspend возвращается после возврата обработчика, восстанавливая заблокированный набор до его состояния при вызове sigsuspend.

Функция sigsuspend эквивалентна атомарной (непрерывной) версии следующего:

1       sigprocmask(SIG_BLOCK, &mask, &prev);
2       pause();
3       sigprocmask(SIG_SETMASK, &prev, NULL);

Насколько я понимаю, sigprocmask(SIG_BLOCK, &mask, &prev) должен привести к тому, что заблокированный набор будет ИЛИ-обработан с маской, т.е. добавит сигналы в маске к тем, которые уже находятся в заблокированном наборе.Но текст прямо над кодом (и man-страница для sigsuspend, которую я посмотрел) говорит, что sigsuspend «временно заменяет текущий заблокированный набор маской».Для меня это больше похоже на sigprocmask(SIG_SETMASK, &mask, &prev), когда заблокированный набор просто устанавливается равным сигналам в маске.

Так почему sigsuspend(&mask) эквивалентен приведенному выше коду (строки 1-3), а не коду ниже?(строки 4-6)?Где я ошибся в своей интуиции и / или понимании функций signal.h?

4       sigprocmask(SIG_SETMASK, &mask, &prev);
5       pause();
6       sigprocmask(SIG_SETMASK, &prev, NULL);

Если мне неясно, позвольте мне вместо этого задать конкретный вопрос (это может объяснить мою интуицию лучше),Скажем, текущий заблокированный набор кодирует SIGCHLD, а маска sigset_t кодирует SIGINT.Я звоню sigsuspend(&mask).Независимо от того, какая интерпретация кода правильная (строки 1-3 ИЛИ 4-6), сигнал SIGINT, доставленный сразу после вызова sigsuspend, будет заблокирован / не активировать процесс.Однако что если сразу после вызова sigsuspend поступит сигнал SIGCHLD?Будет ли процесс просыпаться / получать сигнал?Моя интуиция говорит, что строки 1-3 будут блокировать SIGCHLD, а строки 4-6 - нет, поэтому строки 1-3 и 4-6 явно не эквивалентны.Но моя интуиция также говорит, что sigsuspend не должен блокировать SIGCHLD, потому что он не в маске, поэтому строки 4-6 верны, и если строки 4-6 эквивалентны sigsuspend в этом случае, sigsuspend не может быть эквивалентен строкам 1-3.Где моя интуиция / понимание пошло не так?

1 Ответ

2 голосов
/ 18 апреля 2019

Особенность технических книг (и в частности учебников) заключается в том, что вы всегда должны знать, есть ли опечатки .

Эта ссылка ошибки в этой книге показывают:

Глава 8: Исключительный поток управления
...
...
p.781. В описании sigsuspend во втором абзаце строка 1 должна выглядеть следующим образом:
sigprocmask(SIG_SETMASK, &mask, &prev);
Опубликовано 28.10.2015.Дэйв О'Халларон

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