Механизм сигналов Linux

Механизм сигналов signal является простейшей формой межпроцессного взаимодействия и предназначен для внешнего управления процессами. Каждый сигнал имеет свой обработчик, определяющий поведение процесса при отсылке ему этого сигнала. Этот обработчик является некоторым набором инструкций программы (подпрограммой), которым передается управление при доставке сигнала процессу. Каждому процессу назначаются обработчики «по умолчанию», в большинстве случаев приводящие к завершению процесса.

Механизм сигналов Linux

В листинге ниже показано применение сигнала штатного прерывания процесса №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

Добавить комментарий для Robertniple Отменить ответ