Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
К.Р. Вариант 2.docx
Скачиваний:
3
Добавлен:
24.09.2019
Размер:
32.12 Кб
Скачать

Критические секции

Другое применение набора сигналов - это блокирование определенных или всех сигналов на участке кода, который должен быть выполнен без прерываний. Такой участок кода называется критической секцией. Критические секции создаются при помощи процедурных скобок - вызова функции sigprocmask в начале и конце секции.

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

• временное блокирование сигналов дает способ избавиться от прерываний во время выполнения критичной части программы;

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

• единственный способ проверки появления сигнала – его блокировка.

Все функции блокировки сигналов используют структуру данных sigset_t, называемую “набором сигналов”, для указания какие сигналы будут заблокированы.

Для задания множества сигналов используются следующие функции. В целях безопасности для работы со структурой sigset_t рекомендуется использовать только описываемые функции.

int sigemptyset(sigset_t *SET)

Функция исключает из множества заблокированных все определенные сигналы. Всегда возвращает 0.

int sigfullset(sigset_t *SET)

Функция включает во множество заблокированных все определенные сигналы. Всегда возвращает 0.

int sigaddset(sigset_t *SET, int SIGNUM)

Функция добавляет сигнал SIGNUM в набор сигналов SET. Возвращает 0 в случае успешного выполнения и –1 в случае ошибки. При возникновении ошибки переменная errno может

принимать следующее значение:

EINVAL SIGNUM содержит неправильный номер сигнала.

int sigdelset(sigset_t *SET)

Функция удаляет сигнал SIGNUM из набора сигналов SET. Возвращаемые значения такие же, как и для функции sigaddset.

int sigismember(const sigset_t *SET, int SIGNUM)

Функция проверяет входит ли сигнал SIGNUM в набор сигналов SET. Возвращает 1, если сигнал находится в наборе и 0 в противном случае, -1 – в случае ошибки выполнения. При возникновении ошибки переменная errno может принимать следующее значение:

EINVAL SIGNUM содержит неправильный номер сигнала.

Набор сигналов, который заблокирован в данный момент, называется “маской сигналов”. Каждый процесс имеет свою собственную маску сигналов. При создании нового процесса, он наследует маску сигналов родительского процесса. Для модификации маски сигналов используется следующая функция:

int sigprocmask(int HOW, const sigset_t *SET, sigset_t *OLDSET)

Аргумент HOW определяет каким образом изменяется маска сигналов и может принимать следующие значения:

SIG_BLOCK сигналы, задаваемые в наборе, блокируются – добавляются к уже существующей маске сигналов;

SIG_UNBLOCK сигналы, задаваемые в наборе, разблокируются – удаляются из уже существующей маски сигналов процесса;

SIG_SETMASK устанавливает набор сигналов для процесса, старое содержимое маски игнорируется.

Аргумент OLDSET используется для возврата старого содержимого маски сигналов процесса. Функция возвращает 0 в случае успеха и –1 в противном случае. При возникновении ошибки переменная errno может принимать следующее значение:

EINVAL SIGNUM содержит неправильный номер сигнала.

Для проверки того, обработчики каких сигналов активны в настоящий момент

используется следующая функция:

int sigpending(sigset_t *SET)

Функция возвращает информацию об активных в текущий момент сигналах. Если имеется заблокированный сигнал, поступивший процессу, то он также включается в маску сигналов. Возвращает 0 в случае успешного выполнения и –1 в случае ошибки. Критическая секция не будет прерываться сигналами, содержащимися в наборе setX. Но сигналы, поступившие процессу во время выполнения критической секции, не пропадают, а откладываются и "ожидают" процесс на выходе из критической секции. Но, если поступило несколько сигналов одного вида, то для дальнейшей обработки будет отложен только один такой сигнал, а остальные будут утеряны.