rt_sigtimedwait - синхронное ожидание запрошенных
rt_sigtimedwait(2)
синхронное ожидание запрошенных
Other Alias
sigwaitinfo, sigtimedwait
ОБЗОР
#include <signal.h>
int sigwaitinfo(const sigset_t *set, siginfo_t *info);
int sigtimedwait(const sigset_t *set, siginfo_t *info,
const struct timespec *timeout);
Требования макроса тестирования свойств для glibc
(см. feature_test_macros(7)):
sigwaitinfo(), sigtimedwait(): _POSIX_C_SOURCE >= 199309L
ОПИСАНИЕ
sigwaitinfo() приостанавливает исполнение вызывающий нити до тех пор,
пока не будет ожидаться один из сигналов из набора
set (если один из
сигналов в
set уже ожидает обработки вызывающей нитью, то
sigwaitinfo() завершит работу немедленно с возвратом информации об этом
сигнале).
sigwaitinfo() удаляет сигнал из списка сигналов ожидающих обработки и
возвращает номер сигнала как результат работы функции. Если аргумент info
не равен NULL, то в буфер, на который он указывает, записывается структура
типа siginfo_t (см. sigaction(2)), содержащая информацию о сигнале.
Если в set ожидают обработки несколько сигналов, то сигнал, который
получит sigwaitinfo(), определяется согласно обычным правилам
очерёдности; подробней смотрите в signal(7).
Системный вызов sigtimedwait() работает аналогично sigwaitinfo(), за
исключением того, что он имеет дополнительный аргумент timeout, задающий
интервал, на который приостанавливается процесс в ожидании сигнала. Данное
значение интервала будет округлено до точности системных часов, а из-за
задержки при планировании в ядре блокирующий интервал будет немного
больше. Этот аргумент имеет следующий тип:
struct timespec {
long tv_sec; /* секунды */
long tv_nsec; /* наносекунды */
}
Если оба поля структуры равны 0, то исполняется опрос: sigtimedwait()
немедленно завершает работу, либо с информацией о сигнале, предназначенном
вызывающему, либо с ошибкой, если ни один из сигналов в наборе set не
ожидает обработки.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При нормальном завершении работы
sigwaitinfo() и
sigtimedwait()
возвращают номер сигнала (т.е. значение больше нуля). При ошибках оба вызова
возвращают -1 и переменная
errno устанавливается соответственно ошибке.
ОШИБКИ
EAGAIN
Ни одного сигнала в указанном наборе set не появилось для обработки за
время timeout, указанном для sigtimedwait().
EINTR
Ожидание было прервано обработчиком сигнала; см. signal(7). (Этот
обработчик был для другого сигнала, не из набора set.)
EINVAL
Значение timeout некорректно.
СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008.
ЗАМЕЧАНИЯ
При обычном использовании вызывающая программа блокирует сигналы в наборе
set через предыдущий вызов
sigprocmask(2) (для того, чтобы не
сработали обработчики по умолчанию этих сигналов, если они появятся для
обработки между последующими вызовами
sigwaitinfo() или
sigtimedwait()) и не устанавливает обработчики для этих сигналов. В
многонитиевых программах сигнал должен быть заблокирован во всех нитях,
чтобы предотвратить возврат сигнала нити, отличной от той, которая вызвала
sigwaitinfo() или
sigtimedwait()).
Набор сигналов, ожидающих обработки в заданной нити, представляет собой
объединение набора сигналов, ожидающих обработки именно в этой нити и набора
сигналов, ожидающих обработки всем процессом (см. signal(7)).
Попытки ожидания SIGKILL и SIGSTOP просто игнорируются.
Если несколько нитей процесса заблокированы в ожидании одного сигнала(ов) в
sigwaitinfo() или sigtimedwait(), то только одна нить действительно
получит сигнал, если он станет доступен для ожидания всему процессу; какая
именно нить примет сигнал неизвестно.
POSIX оставляет неопределённое значение NULL в аргументе timeout для
sigtimedwait(), допуская возможность того, что он имеет такое же
значение, как и у вызова sigwaitinfo(), и в самом деле это именно так в
Linux.
Отличия между библиотекой C и ядром
В Linux,
sigwaitinfo() реализована в виде библиотечной функции,
использующей
sigtimedwait().
Обёрточные функции glibc для sigwaitinfo() и sigtimedwait() просто
игнорируют попытки ожидания двух сигналов реального времени, которые
используются внутри реализации NPTL. Подробности смотрите в nptl(7).
Первоначально, системный вызов Linux назывался sigtimedwait(). Однако, с
добавлением сигналов реального времени в Linux 2.2, 32-битный аргумент
sigset_t неизменяемого размера, поддерживаемый этим системным вызовом, не
мог больше использоваться. В результате был добавлен новый системный вызов
rt_sigtimedwait() с увеличенным типом sigset_t. У нового системного
вызова появился четвёртый аргумент, size_t sigsetsize, в котором
указывается размер (в байтах) набора сигналов set. В настоящее время
значение этого аргумента должно быть равно sizeof(sigset_t) (иначе
возникает ошибка EINVAL). Обёрточная функция glibc sigtimedwait()
скрывает это и вызывает rt_sigtimedwait(), если он есть в ядре.