Эта программа посылает себе некоторое количество сигналов и выводит на дисплей порядок их получения. Когда сигналы отправляются, она блокирует их, чтобы предотвратить немедленную доставку. Также она блокирует сигналы всякий раз, когда вызывается обработчик, устанавливая значение члена
sa_mask
структуры
struct sigaction
при настройке обработчика для каждого сигнала. Это предотвращает возможное состояние состязаний при обращении к глобальным переменным
nextSig
и
sigOrder
изнутри обработчика.
Запуск этой программы выдаст показанные ниже результаты.
Принятые сигналы:
User defined signal1
SIGRTMIN + 0
SIGRTMIN + 0
SIGRTMIN + 0
SIGRTMIN + 1
SIGRTMIN + 1
Это
показывает, что все сигналы реального времени были доставлены, в то же время, был доставлен только один экземпляр сигнала
SIGUSR1
. Вы также видите изменение порядка сигналов реального времени — все сигналы
SIGRTMIN
были доставлены перед
SIGRTMIN + 1
.
12.7. Дополнительные сведения о сигналах
Сигналы, которые мы обсуждали до сих пор, не несли в себе никаких данных; появление сигнала — это единственная информация, которую получает приложение. В некоторых случаях было бы неплохо знать, что послужило причиной отправки сигнала (как, например, неправильная адресация памяти, генерирующая
SIGSEGV
), или же иметь возможность включить данные в сигналы, генерируемые приложением. Расширение реального времени Real Time Signals позволяет решить обе эти задачи.
12.7.1. Получение контекста сигнала
Информация о том, как и почему был сгенерирован сигнал, называется контекстом[68] сигнала. Приложения, которые должны видеть этот контекст, используют обработчики сигналов, отличающиеся от нормальных. Они включают два дополнительных параметра — указатель на
siginfo_t
, предоставляющий контекст сигнала, и указатель на
void*
, который может быть использован некоторыми низкоуровневыми системными библиотеками [69] . Вот как выглядит полный прототип такого обработчика.
68
До появления стандарта POSIX приложение могло обращаться к
struct sigcontext
за информацией того же рода, что теперь представляет
siginfo_t
, и термин "контекст" остался от этой старой реализации.
69
Этот третий параметр на самом деле указывает на структуру
struct ucontext
, которая позволяет процессам выполнять полное переключение контекстов в пользовательском пространстве. Данные вопросы выходят за пределы тем, рассматриваемых в настоящей книге, но это хорошо документировано в Single Unix Specification.
Приложение должно указать ядру на необходимость передачи полной информации о контексте, устанавливая флаг
SA_SIGINFO
члена
sa_mask
структуры
struct sigaction
, применяемой для регистрации обработчика сигнала. Член
sa_handler
также не используется, потому что он является указателем на функцию с другим прототипом. Вместо этого новый член,
sa_sigaction
, указывает на обработчик сигнала с правильным прототипом. Чтобы снизить потребление памяти,
sa_handler
и
sa_sigaction
разрешено использовать один и тот же участок памяти, поэтому только один из двух должен применяться в одно и то же время. Чтобы сделать это прозрачным, библиотека С определяет