Как послать сигнал процессу linux

Обновлено: 06.07.2024

Сигналы в Unix указывают ядру, что надо прервать нормальное планирование процесса и завершить/остановить его, или, вместо продолжения выполнения процесса с места остановки, выполнить функцию - обработчик сигнала, и лишь затем продолжить выполнение основного кода.

Сигналы, предназначенные процессу, создаются (отправляются) в нескольких ситуациях: при аппаратных сбоях, при срабатывании особого таймера, при обработке спецсимволов (Ctrl C, Ctrl Z) драйвером управляющего терминала, с помощью системного вызова kill(). В зависимости от причины, отправляются сигналы разных типов. Тип сигнала обозначается целым числом (номером). В Linux сигналы нумеруются от 1 до 64. Сигнал может быть отправлен отдельной нити процесса, процессу в целом или группе процессов.

Для каждого номера сигнала в процессе (нити) предусмотрено некоторое действие (действие по умолчанию, игнорирование или вызов пользовательской функции). Доставка сигнала заключается в выполнении этого действия.

Между отправкой сигнала и его доставкой проходит некоторое непредсказуемое время, поскольку, обычно, сигналы обрабатываются (доставляются) при выходе из системных вызовов или в тот момент, когда планировщик назначает процесс на выполнение. Исключением является доставка сигнала SIGKILL остановленным процессам. Для большинства сигналов можно явно приостановить доставку с помощью установки маски блокирования доставки sigprocmask() , и, в случае необходимости, удалить сигнал без обработки с помощью sigwait() .

Сигналы SIGKILL и SIGSTOP не могут быть заблокированы или проигнорированы и на них нельзя установить свой обработчик.

Действия по умолчанию:

  • SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU - остановка процесса
  • SIGCONT - запуск остановленного процесса
  • SIGCHLD - игнорируется
  • SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGSEGV - сохранение дампа памяти и завершение (Linux)
  • остальные - завершение процесса

Сигнал, маска, обработчик

В упрощенном виде структуру в ядре, обеспечивающую доставку сигналов процессу, можно представить как таблицу:

Традиционно, при отправке процессу нескольких однотипных обычных сигналов, обработчик будет вызван лишь раз. Начиная с POSIX 1003.1, кроме обычных сигналов, поддерживаются сигналы реального времени, для которых создаётся очередь недоставленных сигналов, которая кроме номера сигнала, содержит значение (целое или адрес), которое уникально для каждого экземпляра сигнала.

Примеры использования сигналов

SIGKILL, SIGTERM, SIGINT, SIGHUP - завершение процесса. SIGKILL - не может быть проигнорирован, остальные могут. SIGTERM - оповещение служб о завершении работы ОС, SIGINT - завершение программы по нажатию Ctrl C, SIGHUP - оповещение программ, запущенных через модемное соединение, об обрыве связи (в настоящее время практически не используется).

SIGILL, SIGFPE, SIGBUS, SIGSEGV - аппаратный сбой. SIGILL - недопустимая инструкция CPU, SIGFPE - ошибка вычислений с плавающей точкой (деление на ноль), SIGBUS - физический сбой памяти, SIGSEGV - попытка доступа к несуществующим (защищенным) адресам памяти.

SIGSTOP, SIGCONT - приостановка и продолжение выполнения процесса

SIGPIPE - попытка записи в канал или сокет, у которого нет читателя

SIGCHLD - оповещение о завершении дочернего процесса.

Список сигналов

Особый сигнал с номером 0 фактически не доставляется, а используется в вызове kill() для проверки возможности доставки сигнала определённому процессу.

В Linux используется 64 сигнала. Список можно посмотреть в терминале командой kill -l

Posix.1-1990

Источник - man 7 signal

int kill(pid_t pid, int signum);

Для отправка сигнала необходимо, чтобы uid или euid текущего процесса был равен 0 или совпадал с uid процесса получателя.

Получатель сигнала зависит от величины и знака параметра pid :

  • pid > 0 - сигнал отправляется конкретному процессу
  • pid == 0 - сигнал отправляется всем членам группы
  • pid == -1 - сигнал отправляется всем процессам кроме init (в Linux'е еще кроме себя)
  • pid < -1 - сигнал отправляется группе с номером -pid

Если signum == 0 - сигнал не посылается, но делается проверка прав на посылку сигнала и формируются код ответа и errno.

int sigqueue(pid_t pid, int sig, const union sigval value);

Отправка сигнала текущему процессу. Эквивалент kill(getpid(),signum);

Убирает из маски сигналов сигнала SIGABRT и отправляет его текущему процессу . Если сигнал перехватывается или игнорируется, то после возвращения из обработчика abort() завершает программу. Выхода из функции abort() не предусмотрено. Единственный способ продолжить выполнение - не выходить из обработчика сигнала.

Отправка сигнала SIGALRM себе через time секунд. Возвращает 0 если ранее alarm не был установлен или число секунд остававшихся до срабатывания предыдущего alarma. Таймер управляющий alarm'ами один. Соответственно установка нового alarm'а отменяет старый. Параметр time==0 позволяет получить оставшееся до alarm'а время без установки нового.

Установка реакции на сигнал через функцию signal() не до конца стандартизована и сохраняется для совместимости с историческими версиями Unix. Не рекомендуется к использованию. В стандарте POSIX signal() заменен на вызов sigaction(), сохраняющий для совместимости эмуляцию поведения signal().

sighandler - адрес функции обработчика void sighandler(int) или один из двух макросов: SIG_DFL (обработчик по умолчанию) или SIG_IGN (игнорирование сигнала).

signal(. ) возвращает предыдущее значение обработчика или SIG_ERR в случае ошибки.

В Linux и SysV при вызове sighandler обработчик сбрасывается в SIG_DFL и возможна доставка нового сигнала во время работы sighandler . Такое поведение заставляет первой строкой в sighandler восстанавливать себя в качестве обработчика сигнала, и, даже в этом случае, не гарантирует от вызова обработчика по умолчанию. В BSD системах сброс не происходит, доставка новых сигнала блокируется до выхода из sighandler .

Параметры для установки обработчика сигнала через sigaction()

Данные, передаваемые в обработчик сигнала sa_sigaction()

В Linux структура siginfo_t содержит больше полей, но они служат для совместимости и не заполняются.

Все функции блокирования сигналов работают с маской сигналов типа sigset_t. В Linux это 64 бита, т.е. два слова в 32х разрядной архитектуре или одно в 64х разрядной. Выставленный бит в маске сигналов означает, что доставка сигнала с соответствующим номером будет заблокирована. Сигналы SIGKILL и SIGSTOP заблокировать нельзя.

Манипулирование маской

Параметр how определяет операцию над текущей маской. Значения SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK.

Проверка наличия заблокированных сигналов

Очистка заблокированных сигналов

sigwait ожидает блокировки какого-либо из сигналов, указанных в маске, удаляет этот сигнал и возвращает его номер в параметр sig . Если реализация сигналов предусматривает очередь сигналов, то удаляется только один элемент из очереди.

Управляющий терминал, сеанс, группы

Для организации диалоговой работы пользователей в Unix вводится понятие терминальной сессии. С точки зрения пользователя - это процесс работы с текстовым терминалом с момента ввода имени и пароля и до выхода из системы командой logout ( exit , нажатие ^D в пустой строке). Во время терминальной сессии может быть запущено несколько программ, которые будут параллельно выполнятся в фоновом режиме и между которыми можно переключаться в диалоговом режиме. После завершения терминальной сессии возможно принудительное завершение всех запущенных в ней фоновых процессов.

С точки зрения ядра - терминальная сессия - это группа процессов, имеющих один идентификатор сеанса sid. С идентификатором sid связан драйвер управляющего терминала, доступный всем членам сеанса как файл символьного устройства /dev/tty. Для каждого сеанса существует свой /dev/tty. Управляющий терминал взаимодействует с процессами сеанса с помощью отправки сигналов.

Группа процессов

Группа процессов - инструмент для доставки сигнала нескольким процессам, а также способ арбитража при доступе к терминалу. Идентификатор группы pgid равен pid создавшего её процесса - лидера группы. Процесс может переходить из группы в группу внутри одного сеанса.

Сеанс

Сеанс - средство для контроля путем посылки сигналов над несколькими группами процессов со стороны терминального драйвера. Как правило соответствует диалоговой пользовательской сессии. Идентификатор сеанса sid равняется идентификатору pid, создавшего его процесса - лидера сеанса. Одновременно с сеансом создаётся новая группа с pgid равным pid лидера сеанса. Поскольку переход группы из сеанса в сеанс невозможен, то создающий сеанс процесс не может быть лидером группы.

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

Фоновая группа сеанса

Процессы в фоновой группе выполняются до тех пор, пока не попытаются осуществить чтение или запись через файловый дескриптор управляющего терминала. В этот момент они получают сигнал SIGTTIN или SIGTTOU соответственно. Действие по умолчанию для данного сигнала - приостановка выполнения процесса.


Сигналы использовались еще с Bell Labs UNIX в 1970 и сегодня официально определено стандартом POSIX. Когда сигнал поступает на процесс, операционная система прерывает нормальный поток выполнения процесса и обеспечивает уведомление.

Команды kill и сигналы

Вы можете просмотреть все сигналы с помощью команды:

kill -l на macos

kill -l на macos

kill -l на centos

kill -l на centos

kill -l на Debian

kill -l на Debian

Я постараюсь рассказать о всех сигналах, но для самого начала поговорим только о самых важных и часто использующихся.

Основные сигналы

Следующие сигналы являются частью стандарта POSIX. Каждый сигнал макрос, определенный в <signals.h> Файл заголовка системы. Они, как правило, сокращенны, без их SIG- префикса; например SIGHUP часто называют просто как HUP.

SIGKILL – сигнал SIGKILL заставляет процесс прекратить выполнение своей работы немедленно. Программа не может игнорировать этот сигнал. Несохраненный прогресс будет потерян.

Синтаксис команды такой:

Если вы не знаете какой нужно использовать PID приложения которого следует избавиться, то запустите команду:

А если знаете конкретное приложение (например apache), то можно отсеять ненужное и вывести все процессы по данной службе:

И это отобразит все запущенные приложения вместе с его PID-ом(ами).

Например, чтобы убить приложение, я выполните следующую команду:

Перезагурзить конфигурационные файлы или перезапуск утилит:

Особенно полезными сигналы включают HUP, INT, kill, STOP, CONT, и 0.

-s signal_name
Символическое имя сигнала, задающее сигнал для отправки сигнала не по умолчанию.

-l [exit_status]
Если операнд не указан, то показать имена сигналов; В противном случае, написать название сигнала, соответствующего exit_status.

-signal_name
Символическое имя сигнала, задающее сигнал для отправки в TERM по умолчанию.

-signal_number
Неотрицательное десятичное целое, задающее сигнал для отправки в TERM по умолчанию.

Следующие PID-ы, имеют особое значение:
-1 Если суперпользователь, то транслирует сигнал всем процессам; в противном случае вещает на все процессыbelong-
ing для пользователя.

Некоторые из наиболее часто используемых сигналов:

PKill

Так как он соответствует шаблону регулярного выражения, вы также можете ввести часть имени процесса, например:

pgrep -l

Killall

В Gnome, вы можете перезапустить Nautilus с помощью команды:

xkill

Еще сигналы которые используются

SIGABRT

Этот сигнал посылает сигнал процессу, чтобы прервать операцию. ABRT как правило, направлен на сам процесс, когда он вызывает функцию abort() языка программирования С, чтобы сигнализировать аварийное завершение, но он может быть направлен из любого процесса, как и любой другой сигнал.

SIGALRM, SIGVTALRM и SIGPROF

ALRM, VTALRM и / или сигнал PROF отправляется процессу, когда лимит времени, указанный при вызове функции сигнализации (например, setitimer) истекает.

ALRM

Посылается, когда настоящее время или часы с течением времени.

VTALRM

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

PROF

Посылается, когда процессорное время, используемое процессом и системы от имени процесса истекает.

SIGBUS

BUS сигнал посылает процессу, когда это приводит к ошибке шины. Условия, которые приводят к данному сигналу, например, неправильное выравнивание доступа к памяти или отсутствие физического адреса.

SIGCHLD

SIGCONT

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

SIGFPE

Сигнал FPE посылает процессу, когда он выполняет ошибочное, арифметические срабатывания, например, такие как деление на ноль.

SIGHUP

SIGILL

ILL сигнал, посылаемый процессу при попытке выполнить вредоносные, неизвестные или привилегированные команды (инструкции).

SIGINT

SIGKILL

Сигнал KILL посылает процессу чтобы он немедленно прекратил работу. В отличие от SIGTERM и SIGINT этот сигнал не может быть захвачен или проигнорирован и принимающий процесс не может выполнить какие-либо очистку после получения этого сигнала.

SIGPIPE

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

SIGQUIT

QUIT сигнал посылается процессу от его управляющего терминала, когда пользователь запрашивает процесс выполнения дампа.

SIGSEGV

Сигнал SEGV отправляется в процесс, когда он делает недопустимую ссылку виртуальной памяти или сбой сегментации, то есть когда он выполняет нарушение сегментации.

SIGSTOP

STOP сигнал указывает ОС, чтобы остановить процесс для последующего возобновления.

SIGTERM

SIGTSTP

Сигнал TSTP посылается в процесс его управляющего терминала и говорит ему, что нужно временно приостановить. Это обычно инициируется пользователем нажатием Control-Z. В отличие от SIGSTOP, этот процесс может зарегистрировать обработчик сигнала или чтобы игнорировать сигнал.

SIGTTIN и SIGTTOU

В TTIN и TTOU сигналы посылаются процессу, когда он пытается прочитать или записать соответственно с (tty) терминала на заднем плане. Как правило, этот сигнал может быть получен только с помощью процессов находящихся под контролем рабочей панели; демоны не имеют управляющие терминалы и никогда не должны получать этот сигнал.

SIGUSR1 и SIGUSR2

Сигналы USR1 и USR2 отправляются процессу и указывают определенные пользователем условия.

SIGPOLL

Сигнал POLL отправляется в процессе, когда происходит асинхронное событие ввода / вывода.

SIGSYS

Сигнал SYS отправляется в процессе, когда он пропускает плохой аргумент для системного вызова.

SIGTRAP

SIGURG

Сигнал URG отправляется процессу, когда socket имеет срочные или вне диапазона данных, доступных для чтения.

SIGXCPU

Сигнал XCPU отправляется в процессе, когда он использует центральный процессор в течение времени превышающего определенное заданное значение, установленным пользователем. Прибытие сигнала XCPU обеспечивает процессу быстро сохранить все промежуточные результаты и завершиться хорошо, прежде чем он завершиться операционной системы с помощью сигнала SIGKILL.

SIGXFSZ

Сигнал XFSZ отправляется в процессе, когда файл вырастает (превышает заданное значение), чем максимально допустимое значение.

SIGRTMIN to SIGRTMAX

Разные сигналы

Следующие сигналы не стандартизированы POSIX, но иногда используются на некоторых системах.

SIGEMT

Сигнал ЕМТ отправляется в процессе, когда происходит прерывание эмулятора.

SIGINFO

Сигнал INFO отправляется в процессе, когда запрос статуса получен от управляющего терминала.

SIGPWR

Сигнал PWR отправляется в процессе, когда система испытывает сбой питания.

SIGLOST

SIGWINCH

Сигнал WINCH отправляется в процессе, когда его управляющий терминал меняет свой размер.

Отправка сигналов с клавиатуры

Сигналы могут быть отправлены с клавиатуры. Несколько стандартных значений по умолчанию перечислены ниже. По умолчанию сочетания клавиш для отправки сигналов прерывания может быть определен с помощью команды stty.

CTRL-C

CTRL-Z

CTRL-\

CTRL-T

вывод

Добавить комментарий Отменить ответ

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Несмотря на то что Linux стабильнее чем Windows, в плане работы программ и различных сервисов, случается всякое и иногда возникает необходимость завершить процесс Linux. Это может понадобиться, если программа завила, когда вы запустили системный сервис в фоне через терминал, а не систему инициализации, а также во многих других случаях, когда убить процесс Linux проще, чем перезагружать всю систему.

В этой статье мы рассмотрим несколько самых распространенных способов завершить процесс Linux. Опишем подробно как происходит остановка процесса и как все сделать правильно.

Как происходит завершение процесса?

Управление процессами в операционной системе Linux осуществляется с помощью сигналов. В том числе и завершение любого процесса. Сигналы передает система, но также их может передавать пользователь с помощью специальных команд или даже сочетаний клавиш в терминале. Когда процессу приходит сигнал о необходимости завершиться, он должен выполнить некоторые подготовительные действия.

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

  • SIGINT - самый безобидный сигнал завершения, означает Interrupt. Он отправляется процессу, запущенному из терминала с помощью сочетания клавиш Ctrl+C. Процесс правильно завершает все свои действия и возвращает управление;
  • SIGQUIT - это еще один сигнал, который отправляется с помощью сочетания клавиш, программе, запущенной в терминале. Он сообщает ей что нужно завершиться и программа может выполнить корректное завершение или проигнорировать сигнал. В отличие от предыдущего, она генерирует дамп памяти. Сочетание клавиш Ctrl+/;
  • SIGHUP - сообщает процессу, что соединение с управляющим терминалом разорвано, отправляется, в основном, системой при разрыве соединения с интернетом;
  • SIGTERM - немедленно завершает процесс, но обрабатывается программой, поэтому позволяет ей завершить дочерние процессы и освободить все ресурсы;
  • SIGKILL - тоже немедленно завершает процесс, но, в отличие от предыдущего варианта, он не передается самому процессу, а обрабатывается ядром. Поэтому ресурсы и дочерние процессы остаются запущенными.

Важно понимать, что нужно дать процессу возможность завершиться корректно. Желательно, чтобы порты и сокеты были освобождены, закрыты и удаленны временные файлы. Поэтому никогда не передавайте сразу SIGKILL. Передавайте сигналы завершения в последовательности, как они перечислены выше.

Сначала Ctrl+C, если это возможно, затем SIGTERM - он хоть и завершает процесс, но делает эту культурно, и только в крайнем случае SIGKILL. А теперь рассмотрим как убить процесс по pid Linux на практике. Если вы всегда используете SIGKILL, тогда на ум приходит такая картинка:


Как убить процесс Linux?

Для передачи сигналов процессам в Linux используется утилита kill. Ее синтаксис очень прост:

$ kill -сигнал pid_процесса

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

Допустим, у нас выполняется утилита ping. Мы хотим ее завершить с помощью kill. Тогда, сначала мы узнаем ее идентификатор с помощью команды ps:

ps aux | grep ping


В первой строчке отобразится сама утилита ping, а во второй сама программа ps. Берем нужный PID и завершаем процесс с помощью SIGTERM:

kill -TERM 20446


И только если после этой команды процесс продолжил висеть, а это вы можете проверить, выполнив ps. Только теперь можно выполнить SIGKILL:

kill -KILL 20446

Теперь снова проверяем:


Если процесс запущен от суперпользователя, то, естественно, вам нужно использовать sudo. Не всегда удобно уничтожать процесс по его PID, как минимум, потому, что вам этот PID нужно еще узнать. Мы могли бы нагородить сложных конструкций с использованием xargs, чтобы вычислять автоматически pid по имени процесса и сразу же его завершать, но в этом нет необходимости. Уже существуют специальные утилиты.

Как завершить процесс с помощью pkill

Утилита pkill - это оболочка для kill, она ведет себя точно так же, и имеет тот же синтаксис, только в качестве идентификатора процесса ей нужно передать его имя. Утилита сканирует директорию proc и находит PID первого процесса с таким именем, затем отправляет ему SIGTERM. Таким образом, вы можете убить процесс по имени Linux. Например, если мы хотим завершить тот же ping:


Также можно вручную задать тип сигнала:

pkill -TERM ping

Вместо ps, вы можете использовать утилиту pgrep для поиска pid процесса, убедимся что наша программа завершена:


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

Как остановить процесс с помощью killall

killall работает аналогично двум предыдущим утилитам. Она тоже приминает имя процесса в качестве параметра и ищет его PID в директории /proc. Но эта утилита обнаружит все процессы, с таким именем и завершит их. Например:


Как видите, запущено несколько процессов, осталось остановить процесс Linux с помощью killall:


Команда завершит все запущенные утилиты ping, вы можете убедиться в этом еще раз выполнив pgrep:

Выводы

В этой статье мы рассмотрели как убить процесс Linux. Иногда эта задача может быть очень полезной, но важно понимать, что ее нужно выполнять правильно. Нельзя сказать, что передача SIGKILL вместо SIGTERM очень опасна, но так делать не стоит. Надеюсь, эта информация была полезна для вас.


Команда kill в Linux

PID — это PID (числовой идентификатор) процесса или несколько PID процессов, если требуется послать сигнал сразу нескольким процессам.

По умолчанию команда kill шлет сигнал KILL (он также называется SIGKILL и имеет числовое значение 9 ).

Опции

Задает сигнал, который будет послан процессу. Сигнал может задаваться числом или названием. Вывести список всех сигналов.
Если задано значение Сигнал , то вывод зависит от того, чему равно заданное значение Сигнал :
  • числовой номер сигнала — в таком случае будет выведено название сигнала;
  • название сигнала — в таком случае будет выведено числовое значение сигнала.
Вывести список сигналов в табличном виде. Выводится числовое значение и название каждого сигнала.

Примеры использования команды kill

Определить PID процесса

Определяем PID процесса. ps ef grep

Вывести список сигналов

Выведем список всех доступных сигналов:

В результате получим список сигналов и их числовые значения:

Список сигналов Linux

Отправка сигнала SIGTERM

Пошлем сигнал SIGTERM процессу с PID 3012:

Отправка сигнала KILL (завершение процесса)

Пошлем сигнал KILL процессу с PID 3121, чтобы принудительно завершить процесс:

Или можно использовать числовое значение сигнала:

Отправка сигнала нескольким процессам

Выполним отправку сигнала KILL сразу нескольким процессам. Для этого необходимо перечислить их идентификаторы:

Читайте также: