Я читал главу моего учебника (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.Где моя интуиция / понимание пошло не так?