Чтение онлайн

на главную - закладки

Жанры

Linux программирование в примерах

Роббинс Арнольд

Шрифт:

 sigaddset(&set, SIGINT); /* Добавить в набор SIGINT */

 sigprocmask(SIG_BLOCK, &set, NULL); /* Заблокировать его */

 act.sa_mask = set; /* Настроить обработчик */

 act.sa_handler = handler;

 act.sa_flags = 0;

 sigaction(sig, &act, NULL); /* Установить его */

 ... /* Возможно, установить отдельные обработчики */

 ... /*
для других сигналов */

 sigemptyset(&set); /* Восстановить пустой, допускает SIGINT */

 for (;;) {

sigsuspend(&set); /* Ждать появления SIGINT */

/* Обработка сигнала. SIGINT здесь снова блокируется */

 }

 /* ...любой другой код... */

 return 0;

}

Ключом к использованию этого является то, что

sigsuspend
временно заменяет маску сигналов процесса маской, переданной в аргументе. Это дает
SIGINT
возможность появиться. При появлении он обрабатывается; обработчик сигнала возвращается, а вслед за ним возвращается также
sigsuspend
. Ко времени возвращения
sigsuspend
первоначальная маска процесса снова на месте.

Вы легко можете расширить этот пример для нескольких сигналов, блокируя в

main
и в обработчике все интересующие сигналы и разблокируя их лишь в вызове
sigsuspended
.

При наличии всего этого не следует в новом коде использовать

pause
.
pause
был стандартизован POSIX главным образом для поддержки старого кода. То же самое верно и для функции
sigpause
System V Release 3. Вместо этого, если нужно структурировать свое приложение с использованием сигналов для IPC, используйте исключительно функции API
sigsuspend
и
sigaction
.

ЗАМЕЧАНИЕ. Приведенный выше код предполагает, что маска сигналов процесса начинается пустой. Код изделия должен вместо этого работать с любой маской сигналов, имеющейся на момент запуска программы.

10.8. Важные сигналы специального назначения

Некоторые сигналы имеют особое назначение. Здесь мы опишем наиболее важные.

10.8.1. Сигнальные часы:

sleep
,
alarm
и
SIGALARM

Часто бывает необходимо написать программу в виде

while (/* некоторое неверное условие */) {

 /* подождать некоторое время */

}

Часто такая потребность возникает в сценариях оболочки, например, в ожидании регистрации определенного пользователя:

until who | grep '^arnold' > /dev/null

do

 sleep 10

done

Два механизма,

один низкоуровневый, другой высокоуровневый, позволяют работающему процессу узнать, когда истекло заданное количество секунд.

10.8.1.1. Труднее, но с большим контролем:

alarm
и
SIGALARM

Основным строительным блоком является системный вызов

alarm
:

#include <unistd.h> /* POSIX */

unsigned int alarm(unsigned int seconds);

После того, как

alarm
возвратится, программа продолжает работать. Однако, когда истекают
seconds
секунд, ядро посылает процессу
SIGALARM
. Действием по умолчанию является завершение процесса, но вы скорее всего вместо этого установите обработчик сигнала для
SIGALARM
.

Возвращаемое значение либо 0, либо, если был установлен предыдущий сигнальный интервал, число секунд, остающихся до его завершения. Однако, для процесса имеется лишь один такой сигнальный интервал; предыдущий отменяется, а новый помещается на его место.

Преимуществом здесь является то, что со своим установленным обработчиком вы можете делать при поступлении сигнала все, что хотите. Недостаток же в том, что приходится быть готовым к работе в нескольких контекстах: основном контексте и контексте обработчика сигнала.

10.8.1.2. Простой и легкий:

sleep

Более легкий способ ожидания истечения фиксированного промежутка времени заключается в использовании функции

sleep
:

#include <unistd.h> /* POSIX */

unsigned int sleep(unsigned int seconds);

Возвращаемое значение равно 0, если процесс проспал все отведенное время. В противном случае возвращается оставшееся для сна время. Это последнее значение может возникнуть в случае, если появился сигнал, пока процесс дремал.

ЗАМЕЧАНИЕ. Функция

sleep
часто реализуется через сочетание
signal
,
alarm
и
pause
. Такой подход делает опасным смешивание
sleep
с вашим собственным вызовом
alarm
(или расширенной функцией
setitimer
, описанной в разделе 14.3.3 «Интервальные таймеры
setitimer
и
getitimer
») Чтобы теперь узнать о функции
nanosleep
, см. раздел 14.3.4 «Более точные паузы:
nanosleep
».

10.8.2. Сигналы, управляющие заданиями

Несколько сигналов используются для реализации управления заданиями — возможностью начинать и останавливать задания и перемещать их из фонового режима на передний план и обратно. На уровне пользователя вы, несомненно, проделывали это: использовали CTRL-Z для остановки задания,

bg
для помещения его в фоновый режим, а иногда использовали
fg
для перемещения фонового или остановленного задания на передний план.

Поделиться:
Популярные книги

Первый среди равных. Книга XII

Бор Жорж
12. Первый среди Равных
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Первый среди равных. Книга XII

Я Гордый часть 7

Машуков Тимур
7. Стальные яйца
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Я Гордый часть 7

Инженер Петра Великого

Гросов Виктор
1. Инженер Петра Великого
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Инженер Петра Великого

Я Гордый Часть 3

Машуков Тимур
3. Стальные яйца
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я Гордый Часть 3

Эволюционер из трущоб

Панарин Антон
1. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб

Магнатъ

Кулаков Алексей Иванович
4. Александр Агренев
Приключения:
исторические приключения
8.83
рейтинг книги
Магнатъ

Локки 2. Потомок бога

Решетов Евгений Валерьевич
2. Локки
Фантастика:
городское фэнтези
аниме
попаданцы
5.00
рейтинг книги
Локки 2. Потомок бога

Эволюционер из трущоб. Том 10

Панарин Антон
10. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 10

Наемный корпус

Вайс Александр
5. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
Наемный корпус

На границе империй. Том 10. Часть 6

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 6

Личинка

Привалов Сергей
1. Звездный Бродяга
Фантастика:
боевая фантастика
космическая фантастика
рпг
попаданцы
5.00
рейтинг книги
Личинка

Наследие Маозари 3

Панежин Евгений
3. Наследие Маозари
Фантастика:
рпг
аниме
5.00
рейтинг книги
Наследие Маозари 3

За Горизонтом

Вайс Александр
8. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
За Горизонтом

Идеальный мир для Лекаря 23

Сапфир Олег
23. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 23