Книга: Linux программирование в примерах
10.6.7. Передача сигналов: kill() и killpg()
10.6.7. Передача сигналов: kill()
и killpg()
Традиционная функция Unix для передачи сигналов называется kill()
. Имя несколько неправильное; все, что она делает — отправляет сигнал. (Результатом этого часто является завершение получателя сигнала, но это не обязательно верно. Однако, теперь слишком поздно менять имя.) Функция killpg()
посылает сигнал определенной группе процессов. Объявления следующие:
#include <sys/types.h> /* POSIX */
#include <signal.h>
int kill(pid_t pid, int sig);
int killpg(int pgrp, int sig); /* XSI */
Аргумент sig
является либо именем сигнала, либо 0. В последнем случае сигнал не посылается, но ядро все равно осуществляет проверку ошибок. В частности, это правильный способ проверки существования данного процесса или группы, а также проверки того, что у вас есть разрешение на передачу сигналов процессу или группе процессов kill()
возвращает 0 в случае успеха и -1 при ошибке; errno
указывает на проблему.
Правила для значения pid
несколько запутаны:
pid > 0 pid
является номером процесса, и сигнал посылается этому процессу
pid = 0
Сигнал посылается каждому процессу в группе посылающего процесса.
pid = -1
Сигнал посылается каждому процессу в системе, за исключением специальных системных процессов. Применяется проверка прав доступа. На системах GNU/Linux исключается лишь процесс init
(PID 1), но у других систем могут быть другие специальные процессы.
pid < -1
Сигнал посылается группе процессов, представленной абсолютным значением pid
. Таким образом, вы можете отправить сигнал всей группе процессов, дублируя возможности killpg()
. Эта неортогональность обеспечивает историческую совместимость.
Значение pid
для kill()
сходно со значением для waitpid()
(см. раздел 9.1.6.1 «Использование функций POSIX: wait()
и waitpid()
»).
Стандартная функция С raise()
в сущности эквивалентна
int raise(int sig) {
return kill(getpid(), sig);
}
Комитет по стандартизации С выбрал имя raise()
, поскольку С должен работать также в окружениях, не относящихся к Unix, a kill()
была сочтена специфичной для Unix функцией. Представилась также возможность дать этой функции более описательное имя.
killpg()
посылает сигнал группе процессов. Пока значение pgrp
превышает 1, эта функция эквивалентна 'kill(-pgrp, sig)
'. Справочная страница GNU/Linux killpg(2) утверждает, что если pgrp
равно 0, сигнал посылается группе отправляющего процесса (Это то же самое, что и kill()
.)
Как вы могли представить, нельзя послать сигнал произвольному процессу (если вы не являетесь суперпользователем, root
). Для обычных пользователей действительный или эффективный UID отправляющего процесса должен соответствовать действительному или сохраненному set-user-ID получающего процесса. (Различные UID описаны в разделе 11.1.1 «Действительные и эффективные ID».)
Однако SIGCONT
является особым случаем: пока получающий процесс является членом того же сеанса, что и отправляющий, сигнал пройдет. (Сеансы были кратко описаны в разделе 9.2.1 «Обзор управления заданиями».) Это особое правило позволяет управляющей заданиями оболочке продолжать остановленные процессы-потомки, даже если этот остановленный процесс имеет другой ID пользователя.
- 10.6.1. Обнажение проблемы
- 10.6.2. Наборы сигналов: sigset_t и связанные функции
- 10.6.3. Управление маской сигналов: sigprocmask() и др.
- 10.6.4. Перехват сигналов: sigaction()
- 10.6.5. Извлечение ожидающих сигналов: sigpending()
- 10.6.6. Создание возможности для прерывания функций: siginterrupt()
- 10.6.7. Передача сигналов: kill() и killpg()
- 10.6.8. Наша история до настоящего времени, эпизод II
- Глава 10 Передача файлов
- 4.5. Передача товара на комиссию
- Передача прав
- 7.4. Аналоговые перемножители сигналов
- 15.1.3. Обработка сигналов управления заданиями
- Using the kill Command to Control Processes
- 6.4.2. Передача номенклатурных позиций между ячейками склада
- Глава 11 Передача во временное пользование и заказы
- 5.3.8. Защищенная передача данных
- 10.1.3. Передача файлов
- Пример: обработчик управляющих сигналов консоли
- 10.6.4. Перехват сигналов: sigaction()