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

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

Жанры

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

• То, что случается при прерывании сигналом системного вызова, также различается в традиционной и BSD линейках. Традиционные системы возвращают -1 с errno, установленным в

EINTR
. BSD системы повторно запускают системный вызов после возвращения из обработчика. Макрос GLIBC
TEMP_FAILURE_RETRY
может помочь вам написать код для обработки системных вызовов, возвращающих -1 с
errno
, установленным в
EINTR
.

POSIX требует, чтобы частично выполненный системный вызов возвращал успешное завершение, указав, сколько работы было выполнено. Системный вызов, который еще не начал выполняться,

вызывается повторно.

• Механизм

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

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

Несмотря на эти проблемы интерфейса

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

10.5. API сигналов System V Release 3:

sigset
и др.

BSD 4.0 (примерно с 1980 г.) ввел дополнительные функции API для предоставления «надежных» сигналов. [109] В частности, стало возможным блокировать сигналы. Другими словами, программа могла сообщить ядру: «Зависни на этих конкретных сигналах в течении следующего небольшого промежутка времени, затем доставь их мне, когда я буду готов их принять». Большим преимуществом является то, что эта особенность упрощает обработчики сигналов, которые автоматически запускаются со своим заблокированным сигналом (чтобы избежать проблемы одновременной обработки двух сигналов) и, возможно, также и с другими заблокированными сигналами.

109

Для использования API требуется компоновка с отдельной библиотекой, —

ljobs
Примеч. автора.

System V Release 3 (примерно с 1984 г.) приняла эти API и популяризовала их, в большинстве связанных с Unix документации и книгах вы, возможно, увидите, что на эти API ссылаются, как ведущие начало от System V Release 3. Эти функции следующие:

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

int sighold(int sig); /* Добавить sig к маске сигналов процесса */

int sigrelse(int sig); /* Удалить sig из маски сигналов процесса */

int sigignore(int sig); /* Сокращение для sigset(sig, SIG_IGN) */

int sigpause(int sig);

 /* Приостановить процесс, позволить появиться sig */

void (*sigset(int sig, void (*disp)(int)))(int);

 /* sighandler_t sigset(int sig, sighandler_t disp); */

Стандарт POSIX для этих функций описывает их поведение в терминах маски сигналов процесса. Маска сигналов процесса отслеживает, какие сигналы (если они вообще есть) процесс заблокировал в настоящее время. Более подробно это описывается в разделе 10.6.2 «Наборы сигналов:

sigset_t
и связанные функции». В API System V Release 3 нет способа получить или изменить маску сигналов процесса в целом. Функции работают следующим
образом:

int sighold(int sig)

Добавляет

sig
к списку заблокированных процессов (маска сигналов процесса).

int sigrelse(int sig)

Удаляет

sig
из маски сигналов процесса.

int sigignore(int sig)

Игнорирует

sig
. Это вспомогательная функция.

int sigpause(int sig)

Удаляет

sig
из маски сигналов процесса, а затем приостанавливает процесс до появления сигнала (см. раздел 10.7 «Сигналы для межпроцессного взаимодействия»).

sighandler_t sigset(int sig, sighandler_t disp)

Это замена для signal. (Здесь мы использовали обозначение из справочной страницы GNU/Linux, чтобы упростить восприятие объявления функции.)

Для

sigset
аргумент
handler
может быть
SIG_DFL
,
SIG_IGN
или указатель функции, как и для
signal
. Однако, он может равняться также и
SIG_HOLD
. В этом случае
sig
добавляется к маске сигналов процесса, но связанное с ним действие никак не изменяется. (Другими словами, если бы у него был обработчик, он остается тем же; если было действие по умолчанию, оно не изменяется.)

Когда для установки обработчика сигнала используется

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

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

ЗАМЕЧАНИЕ. POSIX стандартизует эти API, поскольку главной целью POSIX является формализация существующей практики, где это возможно. Однако, функции

sigaction
, которые вскоре будут описаны, дают вам все, что делают эти API, и даже больше. В новых программах вам не следует использовать эти API Вместо этого используйте
sigaction
. (Мы заметили, что в справочной системе GNU/Linux нет даже страницы для sigset(2)!)

10.6. Сигналы POSIX

API POSIX основан на API

sigvec
из BSD 4.2 и 4.3. С небольшими изменениями этот API можно было отнести к возможностям API как V7, так и System V Release 3. POSIX сделал эти изменения и переименовал API
sigaction
. Поскольку интерфейс
sigvec
широко не использовался, мы не будем его описывать. Вместо этого в данном разделе описывается только
sigaction
, который вы и должны так или иначе использовать. (На самом деле руководства BSD 4.4 от 1994 г. помечают
sigvec
как устаревшую, указывая читателю на
sigaction
.)

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

Матабар V

Клеванский Кирилл Сергеевич
5. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар V

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

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

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

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

Телохранитель Генсека. Том 4

Алмазный Петр
4. Медведев
Фантастика:
попаданцы
альтернативная история
6.00
рейтинг книги
Телохранитель Генсека. Том 4

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

Тарс Элиан
3. Дважды одаренный
Фантастика:
альтернативная история
аниме
фэнтези
фантастика: прочее
юмористическое фэнтези
5.00
рейтинг книги
Дважды одаренный. Том III

Ратник

Ланцов Михаил Алексеевич
3. Помещик
Фантастика:
альтернативная история
7.11
рейтинг книги
Ратник

Лейтенант. Назад в СССР. Книга 8. Часть 1

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

Я еще царь. Книга XXX

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

Князь Андер Арес 4

Грехов Тимофей
4. Андер Арес
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Князь Андер Арес 4

Имперец. Том 4

Романов Михаил Яковлевич
3. Имперец
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Имперец. Том 4

Одержимый

Поселягин Владимир Геннадьевич
4. Красноармеец
Фантастика:
боевая фантастика
5.00
рейтинг книги
Одержимый

Древесный маг Орловского княжества 5

Павлов Игорь Васильевич
5. Орловское княжество
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Древесный маг Орловского княжества 5

Возлюби болезнь свою

Синельников Валерий Владимирович
Научно-образовательная:
психология
7.71
рейтинг книги
Возлюби болезнь свою

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

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