Linux программирование в примерах
Шрифт:
SI_SIGIO
SIGIO
поставлен в очередь (расширенный).SI_TIMER
SI_USER
kill
. raise
и abort
также могут его вызвать, но это
В особенности полезно значение
SI_USER
; оно позволяет обработчику сигнала сообщить, был ли сигнал послан функциями raise
или kill
(описываются далее). Вы можете использовать эту информацию, чтобы избежать повторного вызова raise
или kill
. Третий аргумент обработчика сигнала с тремя аргументами,
void *contex
t, является расширенной возможностью, которая больше не обсуждается в данной книге. Наконец, чтобы увидеть
sigaction
в действии, исследуйте полный исходный код обработчика сигнала для sort.c
: 2074 static void
2075 sighandler(int sig)
2076 {
2077 #ifndef SA_NOCLDSTOP /* В системе старого стиля... */
2078 signal(sig, SIG_IGN); /* - для игнорирования sig используйте signal*/
2079 #endif - /* В противном случае sig автоматически блокируется */
2080
2081 cleanup; /* Запуск кода очистки */
2082
2083 #ifdef SA_NOCLDSTOP /* В системе в стиле POSIX... */
2084 {
2085 struct sigaction sigact;
2086
2087 sigact.sa_handler = SIG_DFL; /* - Установить действие по умолчанию */
2088 sigemptyset(&sigact.sa_mask); /* - Нет дополнительных сигналов для блокирования */
2089 sigact.sa_flags = 0; /* - Специальные действия не предпринимаются */
2090 sigaction(sig, &sigact, NULL); /* - Поместить на место */
2091 }
2092 #else /* На системе в старом стиле... */
2093 signal(sig, SIG_DFL); /* - Установить действие по умолчанию */
2094 #endif
2095
2096 raise(sig); /* Повторно послать сигнал */
2097 }
Вот код в
main
, который помещает обработчик на свое место: 2214 #ifdef SA_NOCLDSTOP /* На системе POSIX... */
2215 {
2216 unsigned i;
2217 sigemptyset(&caught_signals);
2218 for (i = 0; i < nsigs; i++) /* - Блокировать все сигналы */
2219 sigaddset(&caught_signals, sigs[i]);
2220 newact.sa_handler = sighandler; /* -
Функция обработки сигнала */
2221 newact.sa_mask = caught_signals; /* - Установить для обработчика маску сигналов процесса */
2222 newact.sa_flags =0; /* - Особых флагов нет */
2223 }
2224 #endif
2225
2226 {
2227 unsigned i;
2228 for (i = 0; i < nsigs; i++) /* Для всех сигналов... */
2229 {
2230 int sig = sigs[i];
2231 #ifdef SA_NOCLDSTOP
2232 sigaction(sig, NULL, &oldact); /* - Получить старый обработчик */
2233 if (oldact.sa_handler != SIG_IGN) /* - Если этот сигнал не игнорируется */
2234 sigaction(sig, &newact, NULL); /* - Установить наш обработчик */
2235 #else
2236 if (signal(sig, SIG_IGN) != SIG_IGN)
2237 signal(sig, sighandler); /* - Та же логика со старым API */
2238 #endif
2239 }
2240 }
Мы заметили, что строки 2216–2219 и 2221 могут быть замещены одним вызовом:
sigfillset(&newact.sa_mask)
; Мы не знаем, почему код написан именно таким способом.
Интерес представляют также строки 2233–2234 и 2236–2237, которые показывают правильный способ проверки того, игнорируется ли сигнал, и для установки обработчика лишь в том случае, если сигнал не игнорируется.
ЗАМЕЧАНИЕ. Функции API
sigaction
и signal
не должны использоваться вместе для одного и того же сигнала. Хотя POSIX идет на большие длинноты, чтобы сначала сделать возможным использование signal
, получить struct sigaction
, представляющую диспозицию signal
, и восстановить ее, все равно это плохая мысль. Код будет гораздо проще читать, писать и понимать, если вы используете одну функцию или другую взаимоисключающим образам 10.6.5. Извлечение ожидающих сигналов:
sigpending
Описанный ранее системный вызов
sigpending
позволяет получить набор ожидающих сигналов, т.е тех сигналов, которые появились, но еще не доставлены из-за блокировки: #include <signal.h> /* POSIX */
int sigpending(sigset_t *set);
Помимо разблокировки ожидающих сигналов, чтобы они могли быть доставлены, вы можете решить их игнорировать. Установка действия сигнала
SIG_IGN
вызывает сбрасывание сигнала (даже если он был заблокирован). Сходным образом для тех сигналов, действием по умолчанию для которых является их игнорирование, установка действия в SIG_DFL
также вызывает сбрасывание таких ожидающих сигналов.
Поделиться:
Популярные книги
Страх
2. Дети Арбата
Проза:
историческая проза
9.49
рейтинг книги
Дважды одаренный. Том VIII
8. Дважды одаренный
Фантастика:
боевая фантастика
альтернативная история
аниме
попаданцы
5.00
рейтинг книги
Мастер Трав III
3. Мастер Трав
Фантастика:
фэнтези
рпг
фантастика: прочее
попаданцы
5.75
рейтинг книги
Старый, но крепкий 2
2. Культивация без насилия
Фантастика:
рпг
уся
эпическая фантастика
5.00
рейтинг книги
Двойник Короля
1. Двойник Короля
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Тринадцатый XIII
13. Видящий смерть
Фантастика:
городское фэнтези
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Лекарь Империи 2
2. Лекарь Империи
Фантастика:
городское фэнтези
аниме
дорама
фэнтези
попаданцы
5.00
рейтинг книги
Хозяин Стужи 7
7. Злой Лед
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Потомок бога
1. Локки
Фантастика:
попаданцы
альтернативная история
аниме
сказочная фантастика
5.00
рейтинг книги
Твое сердце будет разбито. Книга 1
Любовные романы:
современные любовные романы
5.50
рейтинг книги
Мой муж – чудовище! Изгнанная жена дракона
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Эволюционер из трущоб. Том 5
5. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Изгой Проклятого Клана. Том 3
3. Изгой
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 4
17. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00