SignalKill(), SignalKill_r()

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

Прототип:

#include <sys/neutrino.h>
int SignalKill( uint32_t nd,
pid_t pid,
int tid,
int signo,
int code,
int value );
int SignalKill_r( uint32_t nd,
pid_t pid,
int tid,
int signo,
int code,
int value );

Аргументы:

nd
Дескриптор узла, на котором необходимо произвести поиск pid и tid. Для поиска на локальном узле следует установить nd в ND_LOCAL_NODE или в 0.
pid
0 или идентификатор процесса (process ID) для отправки сигнала.
tid
0 или идентификатор потока (thread ID) для отправки сигнала.
signo
Сигнал, который требуется отправить. Всего доступно 64 сигнала. Из них по крайней мере 8 являются сигналами реального времени POSIX, которые находятся в диапазоне от SIGRTMIN до SIGRTMAX. Полный список сигналов см. в разделе сигналы POSIX в документации к SignalAction(). Пользовательские сигналы находятся в диапазоне от 1 до (NSIG - 1).
code
value
Код и значение, связанные с сигналом (см. SignalAction()).

Библиотека:

libc

Описание:

Системные вызовы SignalKill() и SignalKill_r() отправляют сигнал signo с кодом code и значением value группе процессов, процессу или потоку.

Эти функции идентичны, за исключением способа уведомления об ошибках.

Если signo равен нулю, сигнал не отправляется, но проверяется достоверность pid и tid. Можно использовать это как тест на существование pid и tid.

SignalKill() реализует возможности функций POSIX kill(), sigqueue() и pthread_kill() в одном вызове. Следует, однако, рассмотреть возможность использования этих функций вместо системных вызовов.

pid и tid определяют цель сигнала следующим образом:

pid tid Цель
=0 Группа процессов отправителя
<0 Группа процессов -pid
>0 =0 Произвольный поток процесса pid
>0 >0 Поток tid в процессе pid

Если целью является поток, сигнал всегда доставляется именно в этот поток. Если поток заблокировал сигнал (см. SignalProcmask()), то он добавляется в очередь ожидающих сигналов.

Если целью является процесс, сигнал доставляется в произвольный поток, у которого данный сигнал разблокирован (см. SignalProcmask(), SignalSuspend() и SignalWaitinfo()). Даже если сигнал разблокирован в нескольких потоках, он доставляется лишь одному потоку. Какой поток получает сигнал заранее не известно. Чтобы детерминировать обрабатывающий поток, можно:

Если все потоки заблокировали сигнал, он начинает ожидать обработки (добавляется в очередь). Первый поток, который разблокирует данный сигнал, получит возможность его обработать. Если сигнал находится в ожидании в потоке, он не будет перенаправлен на обработку в процесс или другой поток, независимо от изменений в маске блокированных сигналов.

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

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

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

Если несколько сигналов доставлены до того, как цель сможет запуститься и обработать сигналы, система ставит их в очередь в порядке приоритета, если бит SA_SIGINFO был установлен для signo. Сигналы с меньшим номером имеют больший приоритет. Если бит SA_SIGINFO не установлен для signo, то в каждый момент времени в очередь ставится не более одного сигнала. Дополнительные сигналы с тем же signo заменяют существующие. Это поведение по умолчанию для обработчиков сигналов POSIX, установленных с использованием старой функции signal(). Более новая функция sigaction() позволяет управлять очередью для каждого сигнала. Сигналы с кодом SI_TIMER никогда не ставятся в очередь.

code и value всегда сохраняются вместе с сигналом. Это позволяет доставлять данные вместе с сигналом независимо от того, был ли установлен SA_SIGINFO для signo. Если SA_SIGINFO установлен, можно использовать сигналы для доставки небольших объемов данных без потерь. Если требуется передать важные данные, можно рассмотреть возможность использования MsgSendPulse() и MsgSendv(), которые доставляют данные с гораздо большей эффективностью.

Когда поток получает сигнал при помощи обработчика сигнала или при помощи вызова SignalWaitinfo(), он может получить signo, code и value из структуры siginfo_t.

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

Если поток доставляет сигналы, которые процесс-получатель пометил как поставленные в очередь, быстрее, чем получатель может их обработать, ядро может завершить вызов, если у него закончатся записи в очереди сигналов. Если signo, code и value не изменяются, ядро выполняет сжатие сигнала, сохраняя 8-битный счет с каждым поставленным в очередь сигналом.

Состояния блокировки:

Отсутствуют. В сети могут выполняться потоки с более низким приоритетом.

Возвращаемое значение:

SignalKill()
Если возникла ошибка функция возвращает -1, код ошибки записывается в errno. Любое другое возвращенное значение считается успешным завершением.
SignalKill_r()
EOK возвращается при успешном завершении. Функция НЕ устанавливает errno. При возникновении ошибки функция возвращает один из представленных ниже кодов.

Коды ошибок:

EINVAL
Значение signo меньше 0 или больше (_NSIG - 1).
ESRCH
Процесс или группа процессов, указанная в pid, или поток, указанный в tid, не существует.
EPERM
У процесса нет разрешения на отправку сигнала любому процессу-получателю.
EAGAIN
Недостаточно ресурсов ядра для постановки сигнала в очередь.

Классификация:

POSIX 1003.1, ЗОСРВ «Нейтрино»

Точка остановки потока
Нет
Обработчик прерываний
Нет
Обработчик сигналов
Да
В потоке
Да

Тематические ссылки:

siginfo_t, pthread_kill(), kill(), SignalAction(), SignalProcmask(), SignalSuspend(), SignalWaitinfo(), sigqueue()




Предыдущий раздел: Описание API системной библиотеки