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

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

Жанры

Linux программирование в примерах
Шрифт:

10.6.1. Обнажение проблемы

Что неладно с API System V Release 3? В конце концов, они предоставляют блокирование сигналов, так, что сигналы не теряются, и любой данный сигнал может быть надежно обработан.

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

С API

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

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

10.6.2. Наборы сигналов:

sigset_t
и связанные функции

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

Маска сигналов процесса программно представляется с помощью набора сигналов. Это тип

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

/* Непосредственное манипулирование маской сигналов. НЕ ДЕЛАЙТЕ ЭТОГО! */

int mask = (1 << SIGHUP) | (1 << SIGINT);

 /* битовая маска для SIGHUP и SIGINT */

Однако, поскольку в системе может быть больше сигналов, чем может содержаться в одной

int
или
long
и поскольку интенсивное использование побитовых операций тяжело для восприятия, для управления наборами сигналов существует несколько функций API.

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

int sigemptyset(sigset_t *set);

int sigfillset(sigset_t *set);

int sigaddset(sigset_t *set, int signum);

int sigdelset(sigset_t *set, int signum);

int sigismember(const sigset_t *set, int signum);

Эти функции следующие:

int sigemptyset(sigset_t *set)

Освобождает набор сигналов. По возвращении

*set
не содержит сигналов. Возвращает 0 в случае успеха и -1 при ошибке.

int sigfillset(sigset_t *set)

Полностью заполняет набор сигналов. По возвращении

*set
содержит все сигналы, определенные системой. Возвращает 0 в случае успеха и -1 при ошибке.

int sigaddset(sigset_t *set, int signum)

Добавляет

signum
к маске сигналов процесса в
*set
. Возвращает 0 в случае успеха и -1 при ошибке.

int sigdelset(sigset_t *set, int signum)

Удаляет

signum
из маски сигналов процесса в
*set
. Возвращает 0 в случае успеха и -1 при ошибке.

int sigismember(const sigset_t *set, int signum)

Возвращает true/false, если

signum
присутствует или не присутствует в
*set
.

Перед выполнением с переменной

sigset_t
каких-то действий всегда следует вызывать одну из функций
sigemptyset
или
sigfillset
. Существуют оба интерфейса, поскольку иногда бывает нужно начать с пустого набора и работать потом лишь с одним или двумя сигналами, а в другое время бывает нужно работать со всеми сигналами, возможно, убирая один или два сигнала.

10.6.3. Управление маской сигналов:

sigprocmask
и др.

Маска сигналов процесса вначале пуста - заблокированных сигналов нет. (Это упрощение; см. раздел 10.9 «Сигналы, передающиеся через

fork
и
exec
.) Три функции позволяют работать непосредственно с маской сигналов процесса:

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

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

int sigpending(sigset_t *set);

int sigsuspend(const sigset_t *set);

Функции следующие:

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset)

Если

oldset
не равен
NULL
, получается маска сигналов текущего процесса и помещается в
*oldset
. Затем маска сигналов процесса обновляется в соответствии с содержимым
set
и значением
how
, который должен иметь одно из следующих значений:

SIG_BLOCK
Объединить сигналы в
*set
с маской сигналов текущего процесса. Новая маска является объединением текущей маски и
*set
.

SIG_UNBLOCK
Удалить сигналы в
*set
из маски сигналов процесса. Это не представляет проблемы, если
*set
содержит сигнал, который не содержится в текущей маске сигналов процесса.

SIG_SETMASK
Заменить маску сигналов процесса содержимым
*set
.

Если

set
равен
NULL
, a
oldset
— нет, значение
how
неважно. Эта комбинация получает маску сигналов текущего процесса, не меняя ее. (Это явно выражено в стандарте POSIX, но не ясно из справочной страницы GNU/Linux.)

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

Вперед в прошлое 7

Ратманов Денис
7. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 7

Кодекс Охотника XXXI

Винокуров Юрий
31. Кодекс Охотника
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Охотника XXXI

Ботаник

Щепетнов Евгений Владимирович
1. Ботаник
Фантастика:
фэнтези
боевая фантастика
4.56
рейтинг книги
Ботаник

Гримуар темного лорда V

Грехов Тимофей
5. Гримуар темного лорда
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Гримуар темного лорда V

Пушкарь. Пенталогия

Корчевский Юрий Григорьевич
Фантастика:
альтернативная история
8.11
рейтинг книги
Пушкарь. Пенталогия

Я снова царь. Книга XXXIII

Дрейк Сириус
33. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я снова царь. Книга XXXIII

"Дальние горизонты. Дух". Компиляция. Книги 1-25

Усманов Хайдарали
Собрание сочинений
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Дальние горизонты. Дух. Компиляция. Книги 1-25

Кукловод

Майерс Александр
4. Династия
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Кукловод

Лекарь Империи 3

Карелин Сергей Витальевич
3. Лекарь Империи
Фантастика:
городское фэнтези
аниме
дорама
фэнтези
попаданцы
5.00
рейтинг книги
Лекарь Империи 3

Кодекс Охотника. Книга XVIII

Винокуров Юрий
18. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XVIII

Родословная. Том 4

Ткачев Андрей Юрьевич
4. Линия крови
Фантастика:
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Родословная. Том 4

Сержант. Назад в СССР. Книга 4

Гаусс Максим
4. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сержант. Назад в СССР. Книга 4

Последний Паладин. Том 6

Саваровский Роман
6. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 6

Я еще не барон

Дрейк Сириус
1. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я еще не барон