Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Processes - Metodicka (edited) with MPI - last....doc
Скачиваний:
59
Добавлен:
22.12.2018
Размер:
1.59 Mб
Скачать
      1. Работа с сигнальной маской.

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

#include <signal.h>

#include <sys/types.h>

#include <stdlib.h>

#include <stdio.h>

int main(int argc, char **argv)

{

sigset_t sigset;

int fl;

sigemptyset(&sigset);

printf("Добавить SIGINT к текущей маске? (yes - 1, no - 0) \n");

scanf("%d", &fl);

if (fl)

{

sigaddset(&sigset, SIGINT);

sigprocmask(SIG_BLOCK, &sigset, NULL);

}

printf("Послать SIGINT? (yes - 1, no - 0)\n");

scanf("%d", &fl);

if (fl)

kill(getpid(), SIGINT);

if (sigprocmask(SIG_BLOCK, NULL, &sigset) == -1)

/* получаем сигнальную маску процесса. Так как второй аргумент NULL, то первый аргумент игнорируется */

{

printf(“Ошибка при вызове sigprocmask()\n”);

return -1;

}

else if (sigismember(&sigset, SIGINT))

/*проверяем наличие сигнала SIGINT в маске*/

{

printf(“Сигнал SIGINT заблокирован! \n”);

sigemptyset(&sigset);

if (sigpending(&sigset) == -1)

/*узнаем сигналы, ожидающие доставки */

{

printf(“Ошибка при вызове sigpending()\n”);

return -1;

}

printf(“Сигнал SIGINT %s\n”, sigismember(&sigset, SIGINT) ? “ожидает доставки” : “не ожидает доставки”);

/*проверяем наличие сигнала SIGINT в маске*/

}

else printf(“Сигнал SIGINT не заблокирован. \n”);

return 0;

}

Для управления работой сигналов используется функция, аналогичная функции signal() в реализации обычных сигналов, но более мощная, позволяющая установить обработку сигнала, узнать ее текущее значение, приостановить получение сигналов:

#include <signal.h>

int sigaction(int sig, const struct sigaction *act, struct *oact)

Аргументами данного вызова являются: номер сигнала, структура, описывающая новую реакцию на сигнал, и структура, через которую возвращается прежний метод обработки сигнала. Если процесс не интересуется прежней обработкой сигнала, он может передать в качестве последнего параметра NULL-указатель.

Структура sigaction содержит информацию, необходимую для управления сигналами. Ее полями являются :

void (*sa_handler) (int),

void (sa_sigaction) (int, siginfo_t*, void*),

sigset_t sa_mask,

int sa_flags

Здесь поле sa_handler — функция-обработчик сигнала, либо константы SIG_IGN или SIG_DFL, говорящие соответственно о том, что необходимо игнорировать сигнал или установить обработчик по умолчанию. В поле sa_mask указывается набор сигналов, которые будут добавлены к маске сигналов на время работы функции-обработчика. Сигнал, для которого устанавливается функция-обработчик, также будет заблокирован на время ее работы. При возврате из функции-обработчика маска сигналов возвращается в первоначальное состояние. В последнем поле указываются флаги, модифицирующие доставку сигнала. Одним из них может быть флаг SA_SIGINFO. Если он установлен, то при получении этого сигнала будет вызван обработчик sa_sigaction, ему помимо номера сигнала также будет передана дополнительная информация о причинах получения сигнала и указатель на контекст процесса.

Итак, «надежные» сигналы являются более мощным средством межпроцессного взаимодействия нежели обычные сигналы. В частности, здесь ликвидированы такие недостатки, как необходимость восстанавливать функцию-обработчик после получения сигнала, имеется возможность отложить получение сигнала на время выполнения критического участка программы, имеются большие возможности получения информации о причине отправления сигнала.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]