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

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

Жанры

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

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

Шрифт:

Функция POSIX API

sigaction
(весьма) запутана из-за необходимости обеспечить:

• обратную совместимость:

SA_RESETHAND
и
SA_RESTART
в поле
sa_flags
;

• выбор, блокировать также полученный сигнал или нет:

SA_NODEFER
для sa
_flags
;

• возможность иметь два различных вида обработчиков сигналов: с одним или с тремя аргументами;

• выбор поведения для управления

SIGCHLD
:
SA_NOCLDSTOP
и
SA_NOCLDWAIT
для
sa_flags
.

Функция

siginterrupt
является удобной для разрешения или запрещения повторного запуска системных вызовов для данного сигнала.

Наконец, для посылки сигналов не только текущему, но также и другим процессам могут использоваться

kill
и
killpg
(конечно, с проверкой прав доступа).

10.7. Сигналы для межпроцессного взаимодействия

«ЭТО УЖАСНАЯ МЫСЛЬ! СИГНАЛЫ НЕ ПРЕДНАЗНАЧЕНЫ ДЛЯ ЭТОГО! Просто скажите НЕТ».

– Джефф Колье (Geoff Collyer) -

Одним из главных механизмов межпроцессного взаимодействия (IPC) являются каналы, которые описаны в разделе 9.3 «Базовая межпроцессная коммуникация каналы и FIFO». Сигналы также можно использовать для очень простого IPC [111] . Это довольно грубо; получатель может лишь сказать, что поступил определенный сигнал. Хотя функция

sigaction
позволяет получателю узнать PID и владельца процесса, пославшего сигнал, эти сведения обычно не очень помогают.

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

111

Наша благодарность Ульриху Дрепперу (Ulrich Drepper) за помощь в разъяснении, связанных с этим проблем — Примеч. автора.

Сигналы в качестве IPC для многих программ могут быть иногда единственным выбором. В частности, каналы не являются альтернативой, если две взаимодействующие программы не запущены общим родителем, а файлы FIFO могут не быть вариантом, если одна из взаимодействующих программ работает лишь со стандартными вводом и выводом. (Примером обычного использования сигналов являются определенные системные программы демонов, таких, как

xinetd
, которые принимают несколько сигналов, уведомляющих, что нужно повторно прочесть файл настроек, осуществить проверку непротиворечивости и т.д. См. xinetd(8) в системе GNU/Linux и inetd(8) в системе Unix.)

Типичная высокоуровневая структура основанного на сигналах приложения выглядит таким образом:

for(;;){

 /* Ожидание сигнала */

 /* Обработка сигнала */

}

Оригинальным интерфейсом V7 для ожидания сигнала является

pause
:

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

int pause(void);

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

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

volatile sig_atomic_t signal_waiting = 0; /* true, если не обрабатываются сигналы */

void handler(int sig) {

 signal_waiting = 1;

 /* Установка других данных, указывающих вид сигнала */

В основном коде флаг проверяется:

for (;;) {

 if (!signal_waiting) { /* Если возник другой сигнал, */

pause; /* этот код пропускается */

signal_waiting = 1;

 }

 /* Определение поступившего сигнала */

 signal_waiting = 0;

 /* Обработка сигнала */

}

К сожалению, этот код изобилует условиями гонки:

for (;;) {

 if (!signal_waiting) {

/* <--- Сигнал может появиться здесь, после проверки условия! */

pause; /* pause будет вызвана в любом случае */

signal_waiting = 1;

 }

 /* Определение поступившего сигнала

<--- Сигнал может переписать здесь глобальные данные */

 signal_waiting = 0;

 /* Обработка сигнала

<--- То же и здесь, особенно для нескольких сигналов */

}

Решением является блокирование интересующего сигнала в любое время, кроме ожидания его появления. Например, предположим, что интересующим нас сигналом является

SIGINT
:

void handler(int sig) {

 /* sig автоматически блокируется функцией sigaction */

 /* Установить глобальные данные, касающиеся этого сигнала */

}

int main(int argc, char **argv) {

 sigset_t set;

 struct sigaction act;

 /* ...обычная настройка, опции процесса и т.д. ... */

 sigemptyset(&set); /* Создать пустой набор */

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

Старый, но крепкий 3

Крынов Макс
3. Культивация без насилия
Фантастика:
рпг
уся
фэнтези
5.00
рейтинг книги
Старый, но крепкий 3

Эмиссар

Листратов Валерий
8. Ушедший Род
Фантастика:
боевая фантастика
аниме
попаданцы
7.50
рейтинг книги
Эмиссар

Газлайтер. Том 28

Володин Григорий Григорьевич
28. История Телепата
Фантастика:
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Газлайтер. Том 28

Сопротивление

Осадчук Алексей Витальевич
11. Последняя жизнь
Фантастика:
аниме
фэнтези
попаданцы
7.33
рейтинг книги
Сопротивление

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

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

Чиновникъ Особых поручений

Кулаков Алексей Иванович
6. Александр Агренев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чиновникъ Особых поручений

Сталин

Радзинский Эдвард Станиславович
3. Загадки жизни и смерти
Проза:
историческая проза
7.36
рейтинг книги
Сталин

Ваше Сиятельство

Моури Эрли
1. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Ваше Сиятельство

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

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

На границе империй. Том 7

INDIGO
7. Фортуна дама переменчивая
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
6.75
рейтинг книги
На границе империй. Том 7

Изменяющий-Механик. Компиляция. Книги 1-18

Усманов Хайдарали
Собрание сочинений
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Изменяющий-Механик. Компиляция. Книги 1-18

Я до сих пор князь. Книга XXII

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

Чужое наследие

Кораблев Родион
3. Другая сторона
Фантастика:
боевая фантастика
8.47
рейтинг книги
Чужое наследие

Дважды одаренный. Том VIII

Тарс Элиан
8. Дважды одаренный
Фантастика:
боевая фантастика
альтернативная история
аниме
попаданцы
5.00
рейтинг книги
Дважды одаренный. Том VIII