next up previous contents
Next: Посылка сигналов с помощью Up: Сигналы Previous: Сигналы   Contents

Понятие о сигналах.

Сигналы являются программными прерываниями, которые посылаются процессу, когда случается некоторое событие. Сигналы могут возникать синхронно с ошибкой в приложении, например SIGFPE(ошибка вычислений с плавающей запятой) и SIGSEGV(ошибка адресации), но большинство сигналов является асинхронными. Сигналы могут посылаться процессу, когда система обнаруживает программное событие, например, когда пользователь дает команду прервать или остановить выполнение, или сигнал на завершение от другого процесса. Сигналы могут прийти непосредственно от ядра ОС, когда возникает сбой аппаратных средств ЭВМ. Система определяет набор сигналов, которые могут быть отправлены процессу. В Linux существует примерно 30 различных сигналов. При этом каждый сигнал имеет целочисленное значение и приводит к строго определенным действиям.

Механизм передачи сигналов состоит из следующих частей:

Отдельные сигналы разделяются на три различных класса:

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

Существует три основных варианта реакции на сигналы:

Чтобы реагировать на те или другие сигналы, необходимо понимать концепции обработки сигнала. Процесс должен организовать так называемый обработчик сигнала. Эти обработчики срабатывают в случае прихода сигнала. Для этого используется функция signal().

#include <signal.h>

void(*signal(int signr, void(*sighandler)(int)))(int);

Такой прототип очень сложен для понимания. Следует упростить его, определив тип для функции обработки.

typedef void signalfunction(int);
После этого прототип функции примет вид:

signalfunction *signal(int signr,signalfunction *sighandler);
signr устанавливает номер сигнала, для которого устанавливается обработчик. В заголовочном файле <signal.h> определены следующие сигналы (табл. 1).

Табл. 1. Сигналы ОС Linux.

Номер Значение Реакция программы по умолчанию

Переменная sighandler определяет функцию обработки сигнала. В заголовочном файле <signal.h> определены две константы SIG_DFL и SIG_IGN. SIG_DFL означает выполнение действий по умолчанию - в большинстве случаев окончание процесса. Например, определение

signal(SIGINT,SIG_DFL);
приведет к тому, что при нажатии на комбинацию клавиш CTRL+C во время выполнения сработает реакция по умолчанию на сигнал SIGINT и программа завершится. С другой стороны, можно определить

signal(SIGINT, SIG_IGN);
Если теперь нажать на комбинацию клавиш CTRL+C, ничего не произойдет, так как сигнал SIGINT игнорируется. Третьим способом является перехват сигнала SIGINT и передача управления на адрес собственной функции, которая должна выполнять действия, если была нажата комбинация клавиш CTRL+C, например...

signal(SIGINT, function);
Пример использования обработчика сигнала (рис. 6):

#include <stdio.h>

#include <stdlib.h>

#include <signal.h>

 

void sigfunc(int sig)

{

  char c;

  if(sig != SIGINT)

  return;

  else

  {

    printf("\nХотите завершить программу (y/n) : ");

    while((c=getchar()) != 'n')

    return;

    exit (0);

  }

}

 

int main()

{

  int i;

  signal(SIGINT,sigfunc);

  while(1)

  {

    printf(" Вы можете завершить программу с помощью CTRL+C ");

    for(i=0;i<=48;i++)

    printf("\b");

  }

  return 0;

}

Рис. 6. Пример обработки сигнала.



2003-12-09