Теория и практика программирования на Си в Unix

       

Сигналы


Сигнал представляет собой программное прерывание, посланное процессу, для того, чтобы сообщить о каком-либо событии, ожидаемом или нет. Источник сигнала не может знать отношение к этому получателя, особенно если последний решил игнорировать получение сигнала: источник об этом просто ничего не узнает! Сигналы могут быть посланы:
- одним процессом другому: в этом случае используется системный вызов kill ();
- ядром процессу (для того, чтобы указать, например, на фатальную ошибку, вызывающую разрушение процесса).
Параметры обработки, принятые по умолчанию при получении сигнала, можно изменить с помощью специального handler (обра- ботчика). Handler связывается с сигналом посредством вызова signal (). Точно также, сигналы можно игнорировать, используя:

signal (NOMSIGNAL, SIG_IGN);

Вызов kill () позволяет послать сигнал процессу (по его PID) или группе процессов (по ее PID).

ПРОГРАММА 4 /*Пpимеp упpавления сигналом SIGINT*/ #include <signal.h>

/*обpаботка связанная с сигналом пpеpывания SIGINT */ tint() { /*вывод на экpан и выход */ printf("signal d'interruption recu\n"); exit(1); }

main() { /*устанавливается обpаботчик сигнала SIGINT */ signal(SIGINT, tint); /*ожидание возможного пpеpывания */ sleep(100); exit(0); }

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

ПРОГРАММА 5

/*Пpимеp блокиpования сигнала*/ #include <stdio.h>

/*глобальная пеpеменная, значение котоpой меняется пpи появлении SIGINT */ int flag = 0;

/*обpаботчик SIGINT */ tint() { /*вывод сообщения и установка флага */ printf("signal d'interruption recu\n"); flag = 1; }

main() { /*блокиpовка SIGQUIT и SIGINT пpи входе в кpитическую область */ #ifdef BSD /*обpаботчик BSD */ int oldmask; oldmask = sigblock(sigmask(SIGQUIT)|sigmask(SIGINT)); /*кpитическая область */ .............. sigsetmask(oldmask); #endif

#ifdef SYS5 /*обpаботчик SYSTEM V */ sighold(SIGQUIT); sighold(SIGINT); /*кpитическая область */ .............. sigrelse(SIGQUIT); sigrelse(SIGINT); #endif

/*безопасное ожидание сигнала SIGINT, устанавливающего флаг flag */ /*установка обpаботчика, связанного с SIGINT */ signal(SIGINT, tint);

#ifdef BSD /*обpаботчик BSD */ sigblock(sigmask(SIGINT)); while (flag == 0) sigpause(0); /*обpаботка сигнала */ .............. #endif

#ifdef SYS5 /*обpаботчик SYSTEM V */ sighold(SIGINT)); while (flag == 0) sigpause(SIGINT); /*обpаботка сигнала */ .............. #endif

exit(0); }



Содержание раздела