Замаскированные сигналы теряются или помещаются в очередь? - PullRequest
0 голосов
/ 15 января 2019

Если я установлю обработчик сигнала (для SIGCHLD) с помощью sigaction без SA_NODEFER и процесс снова получит тот же сигнал, находясь внутри обработчика, будет ли потерян второй сигнал или он будет доставлен, когда обработчик возвращается?

1 Ответ

0 голосов
/ 25 января 2019

Исторически сигналы могли потеряться. Изначально это был просто отсутствующий интерфейс программирования, потому что sigaction и sigprocmask не существовало, поэтому для временной остановки доставки сигнала необходимо было использовать функцию signal с SIG_IGN, и, конечно, во время время SIG_IGN было активным, любой сигнал исчез бы, если бы он поступил в течение этого времени.

При sigprocmask (и уточненной семантике обработчиков сигналов, установленных с sigaction), сигналы могут становиться ожидающими, когда ядро ​​записывает факт наличия сигнала, фактически не доставляя его. Только когда сигнал разблокирован (или явно разблокирован), он потребляется.

Однако ожидающие сигналы являются не просто простыми счетчиками (для каждого сигнала), но несут дополнительную информацию, такую ​​как отправляющий PID и значение сигнала, если сигнал был сгенерирован с использованием sigqueue. Это означает, что ядро ​​фактически должно выделить память, если оно должно было поставить в очередь произвольное количество сигналов. Linux делает это только для сигналов в реальном времени. Существует ограничение для каждого пользователя, RLIMIT_SIGPENDING, для количества сигналов, которые могут быть поставлены в очередь:

$ ulimit -a | grep sign
pending signals                 (-i) 47913

Подробнее см. signal(7).

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

Для некоторых сигналов не в реальном времени, таких как SIGCHLD и SIGIO, может показаться, что они помещены в очередь, но это потому, что они генерируются один раз для конкретных событий (привязанных к некоторым существующим ресурсам ядра, например, как процесс), и несколько таких событий может произойти, пока сигнал заблокирован.

Также см. этот более ранний ответ .

...