Читаем Linux программирование в примерах полностью

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

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

#include /* 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

Перейти на страницу:

Похожие книги

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных