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

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

Жанры

Разработка приложений в среде Linux. Второе издание

Троан Эрик В.

Шрифт:

12.1.4. Сигналы и системные вызовы

Часто сигналы доставляются процессу, который находится состоянии ожидания наступления некоторого внешнего события. Например, текстовый редактор часто ожидает завершения

read
, чтобы возвратить ввод терминала. Когда системный администратор посылает процессу сигнал
SIGTERM
(нормальный сигнал, посылаемый командой
kill
, позволяющий процессу завершиться чисто), то процесс может обработать его, как описано ниже.

1. Не пытаться перехватить сигнал и быть прерванным ядром (обработка

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

2. Перехватить сигнал, очистить терминал с помощью

обработчика этого сигнала, затем выйти. Хотя это кажется привлекательным, в сложных программах трудно написать такой обработчик, который знал бы достаточно о том, что делает программа в момент прерывания, чтобы правильно выполнить очистку.

3. Перехватить сигнал, установить флаг, обозначающий, что сигнал получен, и каким-то образом обеспечить выход из блокирующего системного вызова (в данном случае

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

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

EINTR
, когда они прерываются сигналом, в то время как быстрые системные вызовы завершаются перед тем, как сигнал будет доставлен.

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

wait
, например, не возвращают управление до тех пор, пока дочерние процессы не завершатся. Поскольку невозможно узнать, насколько долго продлится это ожидание, считается, что
wait
— медленный системный вызов. Системные вызовы доступа к файлам рассматриваются как медленные, если они обращаются к медленным файлам, и быстрые — если к быстрым файлам [58] .

58

Разница между быстрыми и медленными файлами та же, что и между быстрыми и медленными системными вызовами, и она обсуждается в главе 11.

Обязанностью процесса является обработка

EINTR
и перезапуск системных вызовов в случае необходимости. Хотя это обеспечивает всю функциональность, которая требуется людям, намного сложнее написать код, который обрабатывает сигналы. Всякий раз когда
read
вызывается на медленном файловом дескрипторе, код должен проверять его возврат на равенство
EINTR
, и перезапускать вызов, либо он не будет делать то, что ожидается.

Чтобы "упростить" ситуацию, 4.2BSD автоматически перезапускает такие системные вызовы (особенно

read
и
write
). Поэтому для большинства операций программы более не должны беспокоиться об
EINTR
, поскольку выполнение системных вызовов продолжится после того, как процесс обработает сигнал. В последних версиях Unix изменен перечень системных вызовов, которые автоматически перезапускаются, a 4.3BSD позволяет вам выбрать, какие системные вызовы перезапускать. Стандарт обработки сигналов POSIX не указывает, какое поведение должно применяться, но все популярные системы согласны в том, как обрабатывать этот случай. По умолчанию системные вызовы не перезапускаются, но для каждого сигнала процесс может установить флаг, который указывает, что система должна перезапускать системные вызовы, прерванные этим сигналом.

12.2. Программный интерфейс сигналов Linux и POSIX

12.2.1. Посылка сигналов

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

kill
. Этот системный вызов подробно обсуждался в главе 10. Вариантом
kill
является
tkill
, который не предназначен для прямого использования в программах.

int tkill(pid_t pid, int signum);

Существуют два отличия

между
kill
и
tkill
[59] . Первое:
pid
должен быть положительным числом;
tkill
не может использоваться для отправки сигналов группам процессов, как это может
kill
. Другое отличие позволяет обработчикам сигналов определять, применялся ли вызов
kill
или
tkill
для генерации сигнала: подробности см. далее в главе.

Функция

raise
, которая представляет собой способ генерации сигналов, указанный ANSI/ISO, использует системный вызов
tkill
для генерации сигналов в системах Linux.

59

Имеются и другие отличия между этими вызовами; они касаются многопоточных программ, которые в настоящей книге не рассматриваются.

int raise(int signum);

Функция

raise
посылает текущему процессу сигнал, указанный в
signum
[60] .

12.2.2. Использование

sigset_t

Большинство функций сигналов POSIX принимают набор сигналов в качестве одного из своих параметров (или части одного из параметров). Тип данных

sigset_t
служит для представления набора сигналов и определен в
<signal.h>
. POSIX определяет пять функций для манипулирования наборами сигналов.

60

В действительности она отправляет сигнал текущему потоку текущего процесса.

#include <signal.h>

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
(никаких сигналов в
set
представлено не будет).
int sigfillset(sigset_t *set);
Включает все доступные сигналы в
set
.
int sigaddset(sigset_t *set, int signum);
Добавляет сигнал
signum
в набор
set
.
int sigdelset(sigset_t *set, int signum);
Удаляет сигнал
signum
из набора
set
.
int sigismember(const sigset_t *set, int signum);
Возвращает не 0, если сигнал
signum
содержится в
set
. В противном случае возвращает 0.

Единственной причиной возврата ошибки любой из этих функций может быть то, что параметр

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

12.2.3. Перехват сигналов

Вместо использования функции

signal
(чья семантика в процессе эволюции стала неправильной) POSIX-программы регистрируют обработчики сигналов с помощью
sigaction
.

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

Измена. Тайный наследник

Лаврова Алиса
1. Тайный наследник
Фантастика:
фэнтези
5.00
рейтинг книги
Измена. Тайный наследник

Инквизитор Тьмы

Шмаков Алексей Семенович
1. Инквизитор Тьмы
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Инквизитор Тьмы

Наследник

Майерс Александр
3. Династия
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Наследник

Ротмистр Гордеев 3

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

(Не)нужная жена дракона

Углицкая Алина
5. Хроники Драконьей империи
Любовные романы:
любовно-фантастические романы
6.89
рейтинг книги
(Не)нужная жена дракона

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

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

Сыночек в награду. Подари мне любовь

Лесневская Вероника
1. Суровые отцы
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Сыночек в награду. Подари мне любовь

Инквизитор Тьмы 2

Шмаков Алексей Семенович
2. Инквизитор Тьмы
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Инквизитор Тьмы 2

Генерал Скала и ученица

Суббота Светлана
2. Генерал Скала и Лидия
Любовные романы:
любовно-фантастические романы
6.30
рейтинг книги
Генерал Скала и ученица

Искатель 1

Шиленко Сергей
1. Валинор
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Искатель 1

Сердце Дракона. Том 10

Клеванский Кирилл Сергеевич
10. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.14
рейтинг книги
Сердце Дракона. Том 10

Печать мастера

Лисина Александра
6. Гибрид
Фантастика:
попаданцы
технофэнтези
аниме
фэнтези
6.00
рейтинг книги
Печать мастера

Выстрел на Большой Морской

Свечин Николай
4. Сыщик Его Величества
Детективы:
исторические детективы
полицейские детективы
8.64
рейтинг книги
Выстрел на Большой Морской

Кодекс Крови. Книга VII

Борзых М.
7. РОС: Кодекс Крови
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VII