Механизм сигналов signal является простейшей формой межпроцессного взаимодействия и предназначен для внешнего управления процессами. Каждый сигнал имеет свой обработчик, определяющий поведение процесса при отсылке ему этого сигнала. Этот обработчик является некоторым набором инструкций программы (подпрограммой), которым передается управление при доставке сигнала процессу. Каждому процессу назначаются обработчики «по умолчанию», в большинстве случаев приводящие к завершению процесса.
В листинге ниже показано применение сигнала штатного прерывания процесса №2 (SIGINT), отсылаемого драйвером терминала всем процессам «переднего» фона при получении символа ^C (ETX), т. е. нажатии клавиш Ctrl+C о на этом терминале. Для процессов «заднего» фона сигнал может быть отослан явно, при помощи команды kill, предназначенной, несмотря на ее название (в большинстве случаев обработчик завершит процесс, отсюда и название), для отсылки сигналов.
Содержимое
Штатное прерывание процесса (^C, Intr, SIGINT)
fltz@ubuntu:~$ 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
fitz@ubuntu:~$ dd if=/dev/zero of=/dev/null
^C782349+0 записей получено
782349+0 записей отправлено
скопировано 400562688 байт (401 МВ), 0,531532 с, 754 МВ/с
fitz@ubuntu:~$ dd if=/dev/zero of=/dev/null &
[1] 23418
fitz@ubuntu:~$ ^C
fitz@ubuntu:~$ ^C
fitz@ubuntu:~$ jobs -l
[1]+ 23418 Выполняется dd if=/dev/zero of=/dev/null &
fitz@ubuntu:~$ kill -SIGINT 23418
fitz@ubuntu:~$ 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)
fitz@ubuntu:~$ dd if=/dev/zero of=/dev/null
^\Выход (сделан дамп памяти)
fitz@ubuntu:~$ dd if=/dev/zero of=/dev/null &
[1] 23429
fitz@ubuntu:~$ kill -SIGQUIT 23429
[1]+ Выход (подготовлен дамп ядра) dd if=/dev/zero of=/dev/null
Некоторые процессы (например, демоны, или графические приложения) не имеют управляющего терминала, поэтому не могут быть завершены интерактивно при помощи Ctrl+C или Ctrl+\. В этом случае используется сигнал штатного завершения № 15 (SIGTERM), что проиллюстрировано в листинге ниже.
Штатное завершение процесса (SIGTERM)
fitz@ubuntu:~$ dd if=/dev/zero of=/dev/null &
[1] 23444
fitz@ubuntu:~$ kill -SIGTERM 23444
fitz@ubuntu:~$
[1]+ Завершено dd if=/dev/zero of=/dev/null
Для приостановки процесса, т. e. временного, исключения его из процедур распределения процессорного времени планировщиком, предназначен сигнал № 19 (SIGSTOP), а для возобновления процесса — сигнал № 18 (SIGCONT). В листинге ниже показано, что приостановленный (sTopped) процесс не потребляет процессорного времени.
Приостановка и возобновление процесса (SIGSTOP и SIGCONT)
fitz@ubuntu:~$ pbzip2 big &
[1] 1647
fitz@ubuntu:~$ 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
fitz@ubuntu:~$ pkill -STOP pbzip2
fitz@ubuntu:~$ 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
fitz@ubuntu:~$ jobs -l
[1]+ 1647 Остановлено (сигнал) pbzip2 big
fitz@ubuntu:~$ 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
fitz@ubuntu:~$ kill -CONT 1647
fitz@ubuntu:~$ 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.
Игнорирование и перехват сигналов
fitz@ubuntu:~$ ps f
PID TTY STAT TIME COMMAND
23025 pts/1 S 0:00 -bash
23771 pts/1 R+ 0:00 \_- ps f
fшtz@ubuntu:~$ bash
fitz@ubuntu:~$ 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
fitz@ubuntu:~$ ^C
fitz@ubuntu:~$ ^\
fitz@ubuntu:~$ 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
fitz@ubuntu:~$ kill -SIGINT 23636
fitz@ubuntu:~$ 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
fitz@ubuntu:~$ kill -SIGKILL 23636
Убито
fitz@ubuntu:~$ 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.
Диспозиция сигналов
fitz@ubuntu:~$ 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
fitz@ubuntu:~$ dc -e 16i2o00384004p
1110000100000000000100
222128 15 87654321
fitz@ubuntu:~$ 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