Специальные сигналы
В ОС QNX Neutrino определено 64 сигнала, которые распределяются в следующих диапазонах.
Таблица 2.14. Диапазоны сигналов
Диапазон | Описание |
1 ... 57 | 57 сигналов стандарта POSIX (включая традиционные UNIX-сигналы) |
41 ... 56 | 16 сигналов реального времени стандарта POSIX (от SIGRTMIN до SIGRTMAX) |
57 ... 64 | 8 специальных сигналов ОС QNX Neutrino |
Указанные восемь специальных сигналов не могут быть игнорированы или перехвачены. Попытка вызвать функцию signal() или sigaction() или выполнить вызов ядра SignalAction() для того, чтобы изменить эти специальные сигналы, будет приводить к ошибке EINVAL.
Кроме того, данные сигналы всегда маскированы и для них включена организация очередей (queuing). Попытка демаскировать эти сигналы с помощью функции sigprocmask() или вызова ядра SignalProcmask() игнорируется.
Обычный сигнал может быть сделан специальным с помощью следующих стандартных вызовов сигналов.
sigset_t *set;
struct sigaction action;
sigemptyset(&set);
sigaddset(&set, signo);
sigprocmask(SIG_BLOCK, &set, NULL);
action.sa_handler = SIG_DFL;
action.sa_flags = SA_SIGINFO;
sigaction(signo, faction, NULL);
Такая конфигурация делает специальные сигналы подходящими для синхронного уведомления посредством функции sigwaitinfo() или вызова ядра SignalWaitinfo(). Следующий пример кода блокируется до получения специального восьмого сигнала:
sigset_t *set;
siginfo_t info;
sigemptyset(&set);
sigaddset(&set, SIGRTMAX + 8);
sigwaitinfо(&set, &info);
printf("Received signal %d with code %d and value %d\n",
info.si_signo,
info.si_code,
info. si_value.sival__int) ;
Поскольку специальные сигналы всегда маскируются, программа не может быть прервана или остановлена в тех случаях, когда специальный сигнал получен вне тела функции sigwaitinfo(). Поскольку очередность сигналов работает всегда, сигналы не теряются — они выстраиваются в очередь для следующего вызова sigwaitinfo().
Специальные сигналы были разработаны для решения общей ситуации межзадачного взаимодействия, когда серверу необходимо уведомить клиента о том, что он может передать ему данные. Для уведомления клиента сервер использует вызов MsgDeliverEvent(). Для передачи этого события внутри уведомления предусмотрено два объекта: импульсы и сигналы.
Импульсы больше подходят для клиентов, которые тоже могут быть серверами для других клиентов. В этом случае клиент создает канал для приема сообщений, который позволяет получить импульсы.
Для большинства простых клиентов дело обстоит иначе. Чтобы получить импульс, простому клиенту придется создать канал специально для этой цели. Если сигнал синхронный (т. е. маскирован) и для него включен механизм очередности, то он может использоваться в качестве импульса. Таким образом, клиент произведет замену вызова MsgReceive(), используемого для ожидания импульса на канале, на простой вызов sigwaitinfo(), служащий для ожидания сигнала.
Дата добавления: 2017-01-29; просмотров: 545;