• SA_NOCLDSTOP
SIGCHLD; флаг указывает системе не генерировать для родительского процесса SIGCHLD от порожденных процессов, которые завершаются посредством SIGSTOP.• SA_SIGINFO
sa_sigaction (при этом поле sa_handler не будет использоваться)[30]. Обработчику будет передаваться дополнительная информация о сигнале — структура siginfo_t (его номер, PID пославшего сигнал процесса, действующий идентификатор пользователя этого процесса). Эта весьма объемная структура будет очень кратко рассмотрена ниже.[31] Ее описание вынесено в отдельный заголовочный файл и может быть изучено там.Приведем несколько небольших и самых простых примеров использования модели надежных сигналов.
1. Перехватчик сигнала SIGINT
void catchint(int signo) {
cout << "SIGINT: signo = " << signo << endl;
}
int main() {
static struct sigaction act = { &catchint, 0, (sigset_t)0 };
// запрещаем любые сигналы на время обработки SIGINT:
sigfillset(&(act.sa_mask));
// до этого вызова реакцией на Ctrl+C будет завершение задачи:
sigaction(SIGINT, &act, NULL);
for (int i = 0; i < 20; i++)
sleep(1), cout << "Cycle # " << i << endl;
}
Результатом нормального (без вмешательства оператора) выполнения приложения будет последовательность из 20 циклов секундных ожиданий, но если в процессе этих ожиданий пользователь пытается прервать работу процесса по [Ctrl+C], то он получит вывод, подобный следующему:
...
Cycle # 10
... здесь пользователь пытается прервать программу
SIGINT: signo = 2
Cycle # 11
...
2. Запрет прерывания выполнения программы с терминала. Для этого достаточно заменить строку инициализации структуры sigaction
static struct sigaction act = { SIG_IGN, 0, (sigset_t)0 };
Можно проигнорировать сразу несколько сигналов (прерывающих выполнение программы с клавиатуры):
sigaction(SIGINT, &act, NULL );
sigaction(SIGQUIT, &act, NULL);
Далее остановимся еще на одном вызове API-сигналов, который широко используется в этой и последующих моделях обработки (сигналы реального времени, реакция в потоках):
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
Этот вызов позволяет прочитать текущее значение (если set
NULL, то параметр how игнорируется) или переустановить сигнальную маску для текущего потока. Параметры вызова:• set
• how
• SIG_BLOCK
• SIG_UNBLOCK
• SIG_SETMASK
set.• oset
Как и большинство сигнальных функций, данная функция возвращает нулевое значение в результате успешного выполнения и -1 в случае неудачи, при этом код ошибки устанавливается в errno
Именно эта функция снимает одно из самых существенных ограничений, свойственных модели «ненадежных сигналов», — позволяет заблокировать реакцию на сигналы при выполнении критических участков кода и восстановить ее при завершении выполнения этих участков.
Модель сигналов реального времени
Сигналы реального времени были добавлены в POSIX относительно недавно (1996 г.). Эта новая модель в различных ОС UNIX реализуется с разной степенью полноты и с отклонениями от спецификаций, и QNX не исключение. Модель еще до конца не отработана, поэтому возможны сюрпризы (и сейчас они будут).