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

51. Последовательность событий

Пример: нажатие клавиши del.

Функции работы управления сигналами (IPC)

- изменение диспозиции сигнала – signal(3c) и sigaction(2).

После функции fork() процесс наследует диспозицию.

После функции exec() устанавливается диспозиция по умолчанию.

#include <signal.h>

void (*signal (int sig, void (*disp(int)))) (int)

sig – сигнал, диспозицию которого хотим поменять, disp – определение новой диспозиции сигнала

1 – обработчик пользователя (SIG_USR1, SIG_USR2), 2 – обработчик по умолчанию (SIG_IGN),

3 – игнорирование (SIG_IGN), не для всех сигналов

При успехе функция возвращает предыдущую диспозицию (необязательно, зависит от системы)

Процесс не может быть заблокирован. Каждый раз при получении сигнала его диспозиция устанавливается по умолчанию. Signal не является стандартной функцией в POSIX.

52. Функции управления процессами

  • signal()

#include <signal.h>.

static void sig_hndl(int signo) // обработчик

{

signal (SIGINT, sig_hndl); // восстановление диспозиции, требуется не всегда

printf(“This is new handler for SIGINT\n”); // сообщение обработчика

}

main()

{

signal(SIGINT, sig_hndl); // смена диспозиции трёх сигналов

signal(SIGUSR1, SIG_DFL);

signal(SIGUSR2, SIG_IGN);

while(1)

pause();

}

$ a.out & - можно пользоваться этим терминалом

5050 - pid порождённого процесса

$ kill SIGINT 5050

This is new handler for SIGINT

$ kill SIGUSR2 5050 - ничего не произойдет

$ kill SIGUSR1 5050 - действие по умолчанию (процесс терминируется).

Функция управления сигналами в POSIX

  • sigaction(2)

Набор сигналов – sigset_t (32 разряда – 32 сигнала). Маскирование сигналов.

Реализация функции sigaction различно в различных ОС (меняется структура, которая ей управляет).

#include <signal.h>

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

Поля структуры sigaction:

- void (*sa_handler) ()

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

- sigset_t sa_mask; // маска

- int sa_flags; // флаги

Если sa_handler <> 0 или sa_sigaction <> 0, то в поле sa_mask передаётся набор сигналов, которые будут добавлены к маске перед вызовом обработчика. Маска блокирует сигналы, которые в неё добавлены. После возврата из обработчика маска восстанавливается. Обрабатываемый сигнал блокируется. Нет очередей сигналов. sa_flags модифицирует доставку сигналов.

siginfo_t – структура-комментарий о сигнале.

#include <siginfo_t.h>

struct siginfo_t{

int sig_no; // номер сигнала

int sig_errno; // номер ошибки

int sig_code; // причина отправки сигнала

};

Функции управления sigaction()

#include <signal.h>

sigemptyset(sig_set_t *set); // начальная инициализация, очистка битов

sigfillset(sig_set_t *set); // включение битов

sigaddset(sig_set_t *set, int signo); // добавить 1 сигнал

sigdelset(sig_set_t *set, int signo); // убрать 1 сигнал

sigismemberset(sig_set_t *set, int signo); // является ли сигнал в маске

Ресурсоемкость сигналов

Для отправки-доставки требуется системный вызов.

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

Для этого необходимо большое число операций со стеком - копирование пользовательского стека в системную область, извлечение параметров системных вызовов, результатов работы системных вызовов и др. Вывод: затраты слишком велики по сравнению с объемом передаваемой информации.

Используются для реакции на событие.

#include <signal.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

void (*oursignal (int signo, void (*hndlr)(int)) (int) // обработчик

{

struct sigaction act, oldact;

act.sa_handler = hndlr;

sigemptyset(&act.sa_mask);

act.sa_flags = 0;

if (signo != SIGALARM) act.sa_flags |= SA_RESTART;

if (sigaction (signo, &act, &oldact) < 0) return (SIG_ERR);

return (oldact.sa_hndlr);

}

static void sig_hndlr (int signo);

{

printf(“We are int handler\n”); // нет восстановления старой диспозиции

}

main()

{

oursignal(SIGINT, sig_hndl); // смена диспозиции трёх сигналов

oursignal(SIGUSR1, SIG_DFL);

oursignal(SIGUSR2, SIG_IGN);

while(1)

pause();

}