Назад

Содержание

Вперед


1.6. Сигналы.

    Для взаимодействия процессов между собой и ядром, в системе UNIX существуют сигналы. Посылаются они в следующих случаях, перечисленных ниже.

  1. При нажатии пользователем определенных клавиш на клавиатуре терминала. Например, <Ctrl+С> - завершить процесс и <Ctrl+Z> - приостановить процесс.
  2. При аппаратных сбоях или попытке выполнения процессом ошибочных с точки зрения системы действий, таких, как деление на ноль или обращение к неверному адресу.
  3. Сигналы могут посылаться одним процессом другому при помощи системного вызова kill( ).
  4. При возникновении программных ошибок в системе, например, при переполнении буфера во время выполнении операции буферизованного вывода.

    Когда программа получает сигнал, вызывается либо функция, зарегистрированная как реакция на него, либо выполняется стандартное действие ОС. Большинство нетривиальных программ в системе UNIX используют сигналы. Каждый сигнал имеет целочисленный идентификатор. Некоторые сигналы являются стандартными. Их идентификаторам соответствуют символические константы, определенные в файле-заголовке <signal.h>.

    Количество стандартных сигналов зависит от версии системы. Ниже приведен перечень, используемый в большинстве диалектов ОС.

SIGABRT Сигнал генерируется вызовом функции abort( ) и вызывает аварийное завершение процесса.
SIGALARM Сигнал посылается по истечении времени, установленного функцией alarm( ).
SIGBUS Сигнал возникает при сбое оборудования.
SIGCONT Сигнал позволяет возобновить выполнение процесса, прерванного по сигналу SIGSTOP.
SIGFPE Ошибка при выполнении арифметической операции с действительными числами.
SIGILL Неверная инструкция процессора при выполнении программы.
SIGINT Сигнал возникает при вводе с терминала <Ctrl+С>.
SIGIO Завершение асинхронной операции ввода-вывода.
SIGIOT Ошибочное завершение асинхронной операции ввода-вывода.
SIGKILL Немедленно завершить процесс.
SIGPIPE Ошибки при записи в канал межпроцессного ввода-вывода (pipe) (см. 1.7.2.).
SIGSEGV Ошибка при использовании процессом неверного адреса.
SIGSTOP Приостановить выполнение процесса.
SIGSYS Ошибка при выполнении системного вызова.
SIGTERM Завершить процесс.
SIGTRAP Аппаратная ошибка при выполнении процесса.
SIGTSTP Ввод с клавиатуры <Ctrl+Z> (приостановить процесс).

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

  1. Процесс может проигнорировать сигнал. Это невозможно только для SIGKILL и SIGSTOP. Эти два сигнала позволяют администратору системы UNIX прерывать или приостанавливать процессы в случае необходимости.
  2. Процесс может зарегистрировать собственную функцию обработки сигнала. Рекомендуется, по возможности, обрабатывать сигналы, приводящие к преждевременному завершению программы.
  3. Если не задана функция обработки сигнала, ядро системы выполняет действия, предусмотренные для его обработки по умолчанию. Если пришел сигнал, связанный с программными и аппаратными ошибками, процесс, как правило, завершается с созданием в текущей директории файла с именем "core". В последний помещается содержимое области оперативной памяти, которая была занята задачей в момент прихода сигнала.

    Для задания способа обработки сигнала используется системный вызов signal( ):

#include <signal.h>

int (*signal (int sig, void (*func) (int))) (int);

    Первый аргумент представляет собой идентификатор сигнала, а второй - адрес функции, производящей обработку. При задании второго аргумента могут быть использованы два специальных значения: SIG_IGN - игнорировать сигнал и SIG_DFL - обработать сигнал стандартным способом. Функция всегда возвращает адрес предыдущей функции обработки сигнала.

    Приведен пример работы с сигналами.

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

void SignalCtrlC (int sig_no) {
  printf ("Receive signal : %d\n", sig_no);
  signal (SIGINT, SignalCtrlC);
};

void main (int argc, char *argv []) {
  char c = 0;
  signal (SIGINT, SignalCtrlC);
  while (c!='q')
    c = getchar( );
}

    Программа заказывает реакцию на нажатие комбинации <Ctrl+C> (SIGINT). После чего ожидается ввод с терминала символа 'q'. Когда он приходит, процесс завершается. Функция SignalCtrlC( ) реагирует на сигнал SIGINT, просто печатая соответствующее сообщение.