Книга: Операционная система UNIX
Сигналы
Сигналы
Сигналы являются способом передачи от одного процесса другому или от ядра операционной системы какому-либо процессу уведомления о возникновении определенного события. Сигналы можно рассматривать как простейшую форму межпроцессного взаимодействия. В то же время сигналы больше напоминают программные прерывания, — средство, с помощью которого нормальное выполнение процесса может быть прервано. Например, если процесс производит деление на 0, ядро посылает ему сигнал SIGFPE
, а при нажатии клавиш прерывания, обычно <Del> или <Ctrl>+<C>, текущему процессу посылается сигнал SIGINT
.
Для отправления сигнала служит команда kill(1):
kill sig_no pid
где sig_nо
— номер или символическое название сигнала, a pid
— идентификатор процесса, которому посылается сигнал. Администратор системы может посылать сигналы любым процессам, обычный же пользователь может посылать сигналы только процессам, владельцем которых он является (реальный и эффективный идентификаторы процесса должны совпадать с идентификатором пользователя[10]). Например, чтобы послать процессу, который вы только что запустили в фоновом режиме, сигнал завершения выполнения SIGTERM
, можно воспользоваться командой:
$ long_program &
Запустим программу в фоновом режиме
$ kill $!
По умолчанию команда kill(1) посылает сигнал SIGTERM; переменная $! содержит PID последнего процесса, запущенного в фоновом режиме
При получении сигнала процесс имеет три варианта действий для выбора:
1. Он может игнорировать сигнал. Не следует игнорировать сигналы, вызванные аппаратной частью, например, при делении на 0 или ссылке на недопустимые области памяти, так как дальнейшие результаты в отношении данного процесса непредсказуемы.
2. Процесс может потребовать действия по умолчанию. Как ни печально, обычно это сводится к завершению выполнения процесса.
3. Наконец, процесс может перехватить сигнал и самостоятельно обработать его. Например, перехват сигнала SIGINT
позволит процессу удалить созданные им временные файлы, короче, достойно подготовиться к "смерти". Следует иметь в виду, что сигналы SIGKILL
и SIGSTOP
нельзя ни перехватить, ни игнорировать.
По умолчанию команда kill(1) посылает сигнал с номером 15 — SIGTERM
[11], действие по умолчанию для которого — завершение выполнения процесса, получившего сигнал.
Иногда процесс продолжает существовать и после отправления сигнала SIGTERM
. В этом случае можно применить более жесткое средство — послать процессу сигнал SIGKILL
с номером (9), — поскольку этот сигнал нельзя ни перехватить, ни игнорировать:
$ kill -9 pid
Однако возможны ситуации, когда процесс не исчезает и в этом случае. Это может произойти для следующих процессов:
? Процессы-зомби. Фактически процесса как такового не существует, осталась лишь запись в системной таблице процессов, поэтому удалить его можно только перезапуском операционной системы. Зомби в небольших количествах не представляют опасности, однако если их много, это может привести к переполнению таблицы процессов.
? Процессы, ожидающие недоступные ресурсы NFS (Network File System), например, записывающие данные в файл файловой системы удаленного компьютера, отключившегося от сети. Эту ситуацию можно преодолеть, послав процессу сигнал SIGINT
или SIGQUIT
.
? Процессы, ожидающие завершения операции с устройством, например, перемотки магнитной ленты.
Сигналы могут не только использоваться для завершения выполнения но и иметь специфическое для приложения (обычно для системных демонов) значение (естественно, это не относится к сигналам SIGKILL
и SIGSTOP
). Например, отправление сигнала SIGHUP
серверу имен DNS named(1M) вызовет считывание базы данных с диска. Для других приложений могут быть определены другие сигналы и соответствующие им значения.
Более подробно сигналы мы рассмотрим в главах 2 и 3.
- Звуковые сигналы BIOS
- 12.6. Сигналы реального времени
- 7.2.6.3. Системные демоны и традиционные сигналы
- Сигналы и шумы
- Световые сигналы
- Глава 10 Сигналы
- 10.3. Стандартные сигналы С: signal() и raise()
- 10.6. Сигналы POSIX
- 10.7. Сигналы для межпроцессного взаимодействия
- 10.8. Важные сигналы специального назначения
- 10.8.2. Сигналы, управляющие заданиями
- 10.9. Сигналы, передающиеся через fork() и exec()