Механизм сигналов signal является простейшей формой межпроцессного взаимодействия и предназначен для внешнего управления процессами. Каждый сигнал имеет свой обработчик, определяющий поведение процесса при отсылке ему этого сигнала. Этот обработчик является некоторым набором инструкций программы (подпрограммой), которым передается управление при доставке сигнала процессу. Каждому процессу назначаются обработчики «по умолчанию», в большинстве случаев приводящие к завершению процесса.
В листинге ниже показано применение сигнала штатного прерывания процесса №2 (SIGINT), отсылаемого драйвером терминала всем процессам «переднего» фона при получении символа ^C (ETX), т. е. нажатии клавиш Ctrl+C о на этом терминале. Для процессов «заднего» фона сигнал может быть отослан явно, при помощи команды kill, предназначенной, несмотря на ее название (в большинстве случаев обработчик завершит процесс, отсюда и название), для отсылки сигналов.
Содержимое
Штатное прерывание процесса (^C, Intr, SIGINT)
[email protected]:~$ stty -а
speed 38400 baud; rows 24; columns 80; line = 0;
intr ^C; quit = ^\; erase ^?; kill = ^U; eof = ^D; eol= M-^7; eol2 = M-^7;
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke
[email protected]:~$ dd if=/dev/zero of=/dev/null
^C782349+0 записей получено
782349+0 записей отправлено
скопировано 400562688 байт (401 МВ), 0,531532 с, 754 МВ/с
[email protected]:~$ dd if=/dev/zero of=/dev/null &
[1] 23418
[email protected]:~$ ^C
[email protected]:~$ ^C
[email protected]:~$ jobs -l
[1]+ 23418 Выполняется dd if=/dev/zero of=/dev/null &
[email protected]:~$ kill -SIGINT 23418
[email protected]:~$ 25318811+0 записей получено
25318810+0 записей отправлено
скопировано 12963230720 байт (13 GB), 17,1001 с, 758 МВ/с
[1]+ Прерывание dd lf=/dev/zero of=/dev/null
Нужно отметить, что настройки драйвера терминала позволяют как переопределить символ, получение которого приведет к выполнению действия intr (посылка сигнала SIGINT), так и совсем выключить отсылку подобных сигналов управления процессами при получении управляющих символов.
В листинге ниже показано аналогичное применение сигнала аварийного завершения процесса №3 (SIGQUIT), посылаемого процессам «переднего» фона при получении драйвером управляющего символа ^\(FS), генерируемого терминалом при нажатии Ctrl + \. Обработчик сигнала не только завершит процесс, но и попытается (если позволяют настройки) сохранить дамп памяти процесса в файл core для последующей отладки.
Аварийное прерывание процесса (^\, quit, SlGQUIT)
[email protected]:~$ dd if=/dev/zero of=/dev/null
^\Выход (сделан дамп памяти)
[email protected]:~$ dd if=/dev/zero of=/dev/null &
[1] 23429
[email protected]:~$ kill -SIGQUIT 23429
[1]+ Выход (подготовлен дамп ядра) dd if=/dev/zero of=/dev/null
Некоторые процессы (например, демоны, или графические приложения) не имеют управляющего терминала, поэтому не могут быть завершены интерактивно при помощи Ctrl+C или Ctrl+\. В этом случае используется сигнал штатного завершения № 15 (SIGTERM), что проиллюстрировано в листинге ниже.
Штатное завершение процесса (SIGTERM)
[email protected]:~$ dd if=/dev/zero of=/dev/null &
[1] 23444
[email protected]:~$ kill -SIGTERM 23444
[1]+ Завершено dd if=/dev/zero of=/dev/null
Для приостановки процесса, т. e. временного, исключения его из процедур распределения процессорного времени планировщиком, предназначен сигнал № 19 (SIGSTOP), а для возобновления процесса — сигнал № 18 (SIGCONT). В листинге ниже показано, что приостановленный (sTopped) процесс не потребляет процессорного времени.
Приостановка и возобновление процесса (SIGSTOP и SIGCONT)
[email protected]:~$ pbzip2 big &
[1] 1647
[email protected]:~$ top -b -n1 -p 1647
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1647 fitz 20 0 102m 33m 900 S 387 0.4 0:25.09 pbzip2
[email protected]:~$ pkill -STOP pbzip2
[email protected]:~$ ps f
PID TTY STAT TIME COMMAND
1640 pts/2 S 0:00 -bash
1647 pts/2 T 0:24 \_ pbzip2 big
1651 pts/2 R+ 0:00 \_ ps f
[email protected]:~$ jobs -l
[1]+ 1647 Остановлено (сигнал) pbzip2 big
[email protected]:~$ top -b -n1 -p 1647
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1647 fitz 20 0 102m 34m 900 T 0 0.4 0:42.90 pbzip2
[email protected]:~$ kill -CONT 1647
[email protected]:~$ top -b -nl -p 1647
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1647 fitz 20 0 102m 34m 900 S 370 0.4 0:51.82 pbzip2
Сигналы могут быть перехвачены, если процесс назначит собственный обработчик, а также проигнорированы, тогда при их доставке вообще никакой обработчик не вызывается. Исключение составляют некоторые «безусловные» «сигналы, такие как № 9 (SIGKILL) — безусловное завершение или № 19 (SIGSTOP) безусловная приостановка процесса.
Игнорирование и перехват сигналов показаны в листинге ниже на примере командного интерпретатора bash. Ни попытки «интерактивного» завершения при помощи сигналов SIGINT и SIGQUIT, ни явная посылка сигналов SIGINT и SIGTERM не приводят к завершению командного интерпретатора. К желаемому результату приводит только явная отсылка сигнала SIGKILL.
Игнорирование и перехват сигналов
[email protected]:~$ ps f
PID TTY STAT TIME COMMAND
23025 pts/1 S 0:00 -bash
23771 pts/1 R+ 0:00 \_- ps f
fш[email protected]:~$ bash
[email protected]:~$ ps f
PID TTY STAT TIME COMMAND
23025 pts/1 S 0:00 -bash
23636 pts/1 S 0:00 \_ bash
23692 pts/1 R+ 0:00 \_ ps f
[email protected]:~$ ^C
[email protected]:~$ ^\
[email protected]:~$ ps f
PID TTY STAT TIME COMMAND
23025 pts/1 S 0:00 -bash
23636 pts/1 S 0:00 \_ bash
23692 pts/1 R+ 0:00 \_ ps f
[email protected]:~$ kill -SIGINT 23636
[email protected]:~$ ps f
PID TTY STAT TIME COMMAND
23025 pts/1 S 0:00 -bash
23636 pts/1 S 0:00 \_ bash
23701 pts/1 R+ 0:00 \_ ps f
[email protected]:~$ kill -SIGKILL 23636
Убито
[email protected]:~$ ps f
PID TTY STAT TIME COMMAND
23025 pts/1 S 0:00 -bash
23771 pts/1 R+ 0:00 \_ ps f
Диспозицию сигналов, т. е. информацию об игнорировании (IGNORED), перехвате (CAUGHT), временной блокировке (BLOCKED) или ожидании доставки (PENDING) сигналов процессов можно получить при помощи команды ps(1), как показано в листинге ниже.
Диспозиция изображается битовой маской, где каждый N-Pi бит маски (нумерация от младших к старшим) соответствует сигналу N. Например, командный интерпретатор игнорирует сигналы, представленные (шестнадцатеричной) маской 0038400416, что в двоичном представлении составляет 11100001000000000001002 и указывает на игнорируемые 3-й, 15-й, 20-й, 21-й и 22-й сигналы т. е. SIGQUIT, SIGTERM, SIGTSTP, SIGTTIN и SIGTTOU.
Для перевода из шестнадцатеричного в двоичное представление .использован стековый калькулятор dc, которому было велено из входной i (input) системы счисления по основанию 16 в выходную о (output) систему счисления по основанию 2 напечатать p (print) число 00384004, а для просмотра имен сигналов по их номерам использована встроенная команда kill.
Диспозиция сигналов
[email protected]:~$ ps s
UID PID PENDING BLOCKED IGNORED CAUGHT STAT TTY TIME COMMAND
1006 23025 00000000 00010000 00384004 4b813efb S pts/5 0:00 -bash
1006 23773 00000000 00000000 00000000 73d3fef9 R+ pts/5 0:00 ps s
[email protected]:~$ dc -e 16i2o00384004p
1110000100000000000100
222128 15 87654321
[email protected]:~$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SKILL 5) SIGTRAP
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SlGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
63) SIGRTMAX-164) SIGRTMAX