Сигналы

Предположим, что есть две программы. Одна программа должна передать другой большое количество данных. Передача данных будет происходить через файл типа FIFO. То есть одна программа открывает этот файл на запись и передает данные, другая должна открыть этот файл на чтение и получить данные. Проблема заключается в том, что вторая программа должна узнать, что пришло время открывать файл и читать данные.

Чтобы уведомить вторую программу, первая может послать ей сигнал. Сигнал — это число. Его можно представить в виде программного прерывания.

Мне сразу вспоминается очень известный анекдот про Петьку и Василия Ивановича:

Летят Петька и Василий Иванович на самолете.

— Петька, прибор!

— 28.

— Что 28?

— А что прибор?

Реакция программы на получаемый сигнал зависит от программиста, написавшего эту программу. Программист, написавший вторую программу из нашего примера, в документации к ней укажет, что если программе послать сигнал, например 10, то она откроет указанный FIFO-файл на чтение.

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

Чтобы получить список всех сигналов, которые поддерживаются системой, используйте программу kill с параметром –l:

$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL
 5) SIGTRAP      6) SIGABRT      7) SIGBUS       8) SIGFPE
 9) SIGKILL     10) SIGUSR1     11) SIGSEGV     12) SIGUSR2
13) SIGPIPE     14) SIGALRM     15) SIGTERM     17) SIGCHLD
18) SIGCONT     19) SIGSTOP     20) SIGTSTP     21) SIGTTIN
22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO
30) SIGPWR      31) SIGSYS      35) SIGRTMIN    36) SIGRTMIN+1
37) SIGRTMIN+2  38) SIGRTMIN+3  39) SIGRTMIN+4  40) SIGRTMIN+5
41) SIGRTMIN+6  42) SIGRTMIN+7  43) SIGRTMIN+8  44) SIGRTMIN+9
45) SIGRTMIN+10 46) SIGRTMIN+11 47) SIGRTMIN+12 48) SIGRTMIN+13
49) SIGRTMIN+14 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8
57) SIGRTMAX-7  58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4
61) SIGRTMAX-3  62) SIGRTMAX-2  63) SIGRTMAX-1
$

Количество поддерживаемых сигналов зависит от типа системы. Даже в разных версиях Linux (имеются в виду версии ядра) может применяться разное количество сигналов. Но их никогда не бывает меньше 32.

Каждый сигнал имеет номер, полное и краткое имена. Например, сигнал 1 имеет полное имя SIGHUP, краткое имя сигнала — HUP.

Внимание! В различных типах UNIX номера сигналов могут не совпадать, поэтому, если вы регулярно работаете в разных UNIX, используйте имена, а не номера сигналов. Тогда вы никогда не ошибетесь при указании сигнала.

Как уже говорилось выше, у программ есть стандартная реакция на получаемые сигналы. Давайте рассмотрим некоторые из них.

Сигнал Описание сигнала Стандартная реакция программы
HUP(1) Сброс. Завершение работы. Для демонов — перечитать конфигурационный файл.
INT(2) Посылается, если нажата комбинация клавиш Ctrl+C. Завершение работы.
KILL(9) Безусловное завершение работы программы. Завершение работы.
TERM(15) Завершение работы программы. Завершение работы.
CONT(18) Продолжение выполнения приостановленной программы. Игнорируется.
STOP(19) Приостановление выполнения программы. Приостановление выполнения программы.

Сигнал TERM(15) посылается программе, если необходимо завершить ее выполнение. При получении этого сигнала программа выполняет все необходимые действия для завершения работы: закрывает соединения, открытые файлы, сохраняет данные. В общем, корректно завершает свою работу.

Теперь представьте, что каким-то чудом (это действительно будет чудо, при условии, что вы правильно управляете Linux-машиной) хакер поставил и запустил программу, которая, например, форматирует ваш диск с проверкой на сбойные блоки в режиме записи (очень длительная процедура). Вы обнаружили эту программу и решили завершить ее работу. При посылке 15-го сигнала программа не завершит работу, т.к. программист ее написавший поставил свой собственный обработчик сигналов. Он, конечно, предусмотрел возможность получения 15-го сигнала, и в ответ на сигнал программа либо просто продолжает свою работу, либо начинает форматировать диск в ускоренном режиме.

В системе предусмотрены сигналы, которые не могут быть переопределены программистом. И это в первую очередь сигнал KILL(9). Но этим сигналом следует пользоваться с особой осторожностью.

Внимание! Посылка сигнала KILL программе аналогична нажатию на кнопку reset, то есть программа завершает работу не корректно! Применять сигнал надо только в том случае, если программа не реагирует на посылку сигнала TERM.

Еще один сигнал, который обрабатывает система, а не программа, — STOP(19). При посылке этого сигнала программе ее выполнение будет приостановлено. Оперативная память, выделенная под программу, не освобождается, просто программа не будет ставится в очередь на выполнение процессору. Продолжить выполнение программы можно послав ей сигнал CONT(18).

Сигнал INT(2) посылается программе, если нажата комбинация клавиш Ctrl+C.

Сигнал HUP(1) посылается программе, если произошло отключение терминала. Действительно, в далекие времена рабочие места подключались через модемы, и при отключении связи программам посылался сигнал HUP. Поскольку ресурсы систем тогда были очень дорогими, система отключала все программы, подключенные к этому терминалу. На данный момент система ведет себя таким же образом, и при завершении работы логин шелл, всем программам посылается HUP, что бы они завершили свою работу. Но есть группа программ, которые в принципе не могут получить HUP — это процессы демоны. В случае демонов сигнал HUP используется по другому. Его посылают для того, что бы программа перечитала свои конфигурационные файлы.