Блокировка сигналов

Для реализации блокировки сигналов используется сигнальная маска. Это набор сигналов, принятие которых будет блокироваться (не обрабатываться) до тех пор, пока они не будут обратно разблокированы. Для управления используется функция

int sigprocmask(int how, const sigset_t *set, sigset_t, *oldset);

выполнение функции зависит от первого аргумента:

SIG_SETMASK маска меняется на значение второго аргумента.

SIG_BLOCK маска set добавляется к текущему (маски объединяются по ИЛИ)

SIG_UNBLOCK сигналы из set удаляются из вызывающего процесса.

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

Если второй аргумент равен NULL, то в третий помещается текущий набор.

#include <sinnal.h>

int sigation(int signo, const struct sigactoin *act, struct sigaction *oldact);

устанавливает действие при получении сигнала. Это действие описывается структурой, передаваемой вторым параметром. Третий параметр, если он не является нулевым, сохраняет предыдущую реакцию на сигнал. При успешном завершении возвращает 0, при ошибке -1;

struct sigaction

{void (*sa_handler)(int);//определяет обработчик на сигнал. Может быть адрес своей функции обработчика, или могут быть значения SIG_DFL ( по умолчанию ), SIG_IGN ( игнорирование )

void (*sa_action)(int)(int, siginfo_t *, void *);

sigset_t sa_mask;//определяет набор сигналов, которые должны блокироваться на время выполнения обработчика. В том числе, и сам сигнал, на который вызывается обработчик. Нельзя заблокировать SIGKILL и SIGSTOP

int sa_flags;//битовая маска, или нулевая, или включающая один или несколько флагов, изменяющих выполнение обработчика. SA_NODEFER // не блокирует обрабатываемый сигнал.

SA_SIGINFO // обработчик сигнала имеет три параметра.

SA_NOCLDWAIT // при появлении сигнала для удаления процесса зомби не потребуется вызывать функцию wait. Обработчик сам вычищает записи о процессе зомби

SA_RESTART// повторная инициализация некоторой функции, во время работы которой поступил сигнал

SA_RESETHAND// обработчик действует на выполнение одного сигнала, и после выполнения устанавливается на выполнение по умолчанию.

}

void my_handler(int signo)

void my_handler(int signo, siginfo_t *si, void ucontext)

siginfo_t

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

int si_errno;//значение ошибки

int si_code;//информация о том, откуда процесс получил сигнал.

}

Поле si_code может иметь значения:

SI_KERNEL //сигнал был сгенерирован ядром

SI_TIMER //был сгенерирован по истечении временного интервала.

SI_USER //сигнал был отправлен SIGKILL & raise

Если обрабатывался сигнал SIGCHLD:

CLD_EXITED //потомок завершился нормально, через exit()

CLD_KILLED //потомок был уничтожен

CLD_STOPPED //потомок был остановлен.

Примеры по работе с сигналами:

Как процессы могут посылать сигналы один одному

#include <unistd.h>

#include <signal.h>

void p_action(int sig)

{printf(“родитель получил сигнал %d \n”, ++n_times);}

void c_action (int sig)

{printf(“сын получил сигнал %d \n”, ++n_times);}

main()

{pid_t pid, ppid; static struct sigaction pact, cact;

pact.sa_handler = p_action;

sigaction(SIGUASR1, &pact, NULL);

switch (pid = fork())

{case -1: exit(-1); break;

case 0: cact.sa_handler = c_action;

sigaction(SIGUSR1, &cact, NULL);

ppid = getppid;

for (;;)

{sleep(1);

kill(ppid, SIGUSR1);

pause();}

default: for (;;)

{pause();

sleep(1);

kill(pid, SIGUSR1);}

}

}

||============================================

#include <unistd.h>

unsigned int alarm(unsigned int secs);

через secs секунд вызывает сигнал SIGALRM

||===========================================

#include <unistd.h> signal.h> <stdio.h>

#define TIMEOUT 5;

#define MAXTRIES 5

#define L_SIZE 100;

#define CTRL_G ‘\007’;

static int time_out; static char answer[L_SIZE];

void catch(int sig)

{time_out = 1; putchar (CTRL_G);}

char *quickreply (char *promt)

{int nt; static struct sigaction act, oact;

act.sa_hanlser = catch;

sigaction (SIGALRM, &act, &oact);

for (nt = 0; nt<MAXTRIES; nt++)

{time_out = 0; printf(“\n %s >”, promt);

alarm(TIMEOUT);

gets(answer);

alarm(0);//остановка таймера

if (!time_out) break;}

sigaction(SIGALRM, &oact, NULL);

{if (nt = MAXTRIES)

return((char*)0);

else return (answer);}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: