Спецификация POSIX гласит:
Функция system () должна игнорировать сигналы SIGINT и SIGQUIT и должна блокировать сигнал SIGCHLD, ожидая завершения команды.Если это может привести к тому, что приложение пропустит сигнал, который убил бы его, то приложение должно проверить возвращаемое значение из system () и предпринять любое действие, соответствующее приложению, если команда прервалась из-за получения сигнала.
Это означает, что у программы, которая запускает длительный подпроцесс, будут SIGINT
и SIGQUIT
заблокированы на долгое время.Вот тестовая программа, скомпилированная на моем ноутбуке Ubuntu 18.10:
$ cat > test_system.c <<< EOF
#include <stdlib.h>
int main() {
system("sleep 86400"); // Sleep for 24 hours
}
EOF
$ gcc test_system.c -o test_system
Если я запускаю эту тестовую программу, работающую в фоновом режиме ...
$ ./test_system &
[1] 7489
.. Тогда я вижу, чтоSIGINT
(2) и SIGQUIT
(3) помечены как игнорируемые в битовой маске.
$ ps -H -o pid,pgrp,cmd,ignored
PID PGRP CMD IGNORED
6956 6956 -bash 0000000000380004
7489 7489 ./test_system 0000000000000006
7491 7489 sh -c sleep 86400 0000000000000000
7492 7489 sleep 86400 0000000000000000
Попытка уничтожить test_system с помощью SIGINT
не имеет никакого эффекта ..
$ kill -SIGINT 7489
.. Но отправка SIGINT
в группу процессов действительно уничтожает его (это ожидается, это означает, что каждый процесс в группе процессов получает сигнал - режим сна завершится и система вернется).
$ kill -SIGINT -7489
[1]+ Done ./test_system
Вопросы
- Какова цель игнорирования
SIGINT
и SIGQUIT
, поскольку процесс все еще можно завершить с помощью группы процессов (это происходит, когда вы делаете ^C
втерминал). - Бонусный вопрос: почему POSIX требует, чтобы
SIGCHLD
был заблокирован? - Обновление Если
SIGINT
и SIGQUIT
игнорируются, чтобы гарантировать, что мыне оставляйте детей, тогда почему нет обработки для SIGTERM
- это сигнал по умолчаниют убить!