#ifdef OLD_SIGNAL

newDisp.sa_flags = SA_RESETHAND | SA_NODEFER;

#else

newDisp.sa_flags = SA_RESTART;

#endif

if (sigaction(sig, &newDisp, &prevDisp) == –1)

return SIG_ERR;

else

return prevDisp.sa_handler;

}

signals/signal.c

Некоторые детали glibc

Реализация функции signal() в библиотеке glibc изменялась с течением времени несколько раз. В современных версиях библиотеки (glibc 2 и новее) по умолчанию предоставляется новая семантика. В старых версиях библиотеки дается более ранняя ненадежная (совместимая с System V) семантика.

Ядро Linux содержит реализацию функции signal() как системного вызова. Эта реализация предоставляет старую ненадежную семантику. Однако библиотека glibc обходит системный вызов, предоставляя библиотечную функцию signal(), осуществляющую вызов sigaction().

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

#define _GNU_SOURCE

#include

void (*sysv_signal(int sig, void (*handler)(int))) (int);

Возвращает предыдущую диспозицию сигнала при успешном завершении или SIG_ERR при ошибке

Функция sysv_signal() принимает те же самые аргументы, что и функция signal().

Если макрос тестирования возможности _BSD_SOURCE не определен при компиляции программы, то библиотека glibc неявно переопределяет все вызовы функции signal() на вызовы sysv_signal(), а это значит, что signal() получает ненадежную семантику сигналов. По умолчанию макрос тестирования возможности _BSD_SOURCE определен, однако он отключается (за исключением случая, когда он определен явным образом) в случае обнаружения при компиляции программы других макросов тестирования возможности, например SVID_SOURCE или _XOPEN_SOURCE.

sigaction() — предпочтительный API для установки обработчика сигнала

Из-за вышеописанных проблем переносимости между ОС System V и BSD (старые и современные версии библиотеки glibc) лучшим подходом всегда является использование функции sigaction(), а не signal() для установки обработчиков сигналов. Мы будем делать именно так в оставшейся части книги. (Альтернатива — написание собственной версии функции signal(), возможно аналогичной листингу 22.1, которая позволит указать собственные флаги по необходимости, и применение этой версии в наших приложениях.) Стоит заметить, что код будет переносимее (и короче) при использовании функции signal() для установки диспозиции по умолчанию сигналов SIG_IGN и SIG_DFL; мы зачастую будем использовать функцию signal() для этих целей.

22.8. Сигналы реального времени

Сигналы реального времени были определены в стандарте POSIX.1b для устранения ограничений, накладываемых стандартными сигналами. По сравнению с ними сигналы реального времени обладают следующими преимуществами.

• Предоставляют дополнительный диапазон сигналов, которые могут применяться для целей, определяемых приложением. Для этого доступны только два стандартных сигнала — SIGUSR1 и SIGUSR2.

• Ставятся в очередь. Если некий сигнал реального времени посылается в процесс несколько раз, значит, процесс и получит его несколько раз. Напротив, при отправке нескольких экземпляров стандартного сигнала, уже находящегося в режиме ожидания процесса, такой сигнал будет доставлен лишь единожды.

• При отправке сигнала реального времени есть возможность указать данные (в виде целого числа или числа с плавающей точкой), которые будут сопровождать сигнал. Обработчик сигнала в целевом процессе может получить эти данные.

• Гарантируется очередность доставки различных сигналов реального времени. Если несколько сигналов реального времени находятся в режиме ожидания, то первым будет доставлен сигнал с наименьшим номером. Иными словами, существует определенная приоритетность сигналов, при которой сигнал с меньшим номером имеет больший приоритет. Если несколько сигналов одного типа находятся в очереди доставки (вместе с сопровождающими их данными), то эти сигналы доставляются в той очередности, в которой они были отправлены.

Согласно требованиям стандарта SUSv3 реализация должна предоставлять как минимум _POSIX_RTSIG_MAX (константа определена со значением 8) различных сигналов реального времени. Ядро Linux определяет 33 различных сигнала реального времени, пронумерованных от 32 до 64. В заголовочном файле определена константа RTSIG_MAX, указывающая количество доступных сигналов реального времени. В файле также определены константы SIGRTMIN и SIGRTMAX, обозначающие наименьший и наибольший доступные номера сигналов реального времени.

Перейти на страницу:

Похожие книги