Файл: Pobegaylo_A._C_Cplus_dlya_studenta.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 13.12.2020

Просмотров: 4276

Скачиваний: 28

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

Часть III. Стандартная библиотека языка программирования C 

376 

В результате работы этой программы на консоль будут выведены 
следующие сообщения: 

Long jump value: 0 
Function is working 
Long jump value: 10 

 


background image

  

 
 

Г Л А В А  

32 

 
 
 

Обработка исключительных 

ситуаций <signal.h> 

32.1. Сигналы 

Сигналы служат для оповещения программы о следующих собы-
тиях: 

 

во время исполнения программы произошла ошибка; 

 

во  время  исполнения  программы  произошло  асинхронное  со-
бытие. 

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

  /* аварийное завершение посредством вызова функции abort */ 
  #define SIGABRT const_int_выражение 
  /* ошибка в операции с плавающей точкой */ 
  #define SIGFPE  const_int_выражение 
  /* неправильная инструкция */ 
  #define SIGILL const_int_выражение 
  /* прерывание */ 
  #define SIGINT const_int_выражение 

  

 


background image

Часть III. Стандартная библиотека языка программирования C 

378 

  /* ошибка доступа к памяти */ 
  #define SIGSEGV const_int_выражение 
  /* сигнал на завершение программы */ 
  #define SIGTERM const_int_выражение 

Здесь 

const_int_выражение

  представляет  собой  выражение,  ре-

зультатом  вычисления  которого  является  неотрицательное  цело-
численное значение. 
Для каждой реализации в заголовочном файле signal.h могут быть 
определены и другие сигналы. 

32.2. Установка функции  
обработки сигнала 

Для установки функции обработки сигнала предназначена функ-
ция 

signal

, которая имеет следующий прототип: 

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

где параметр 

sig

  задает  номер  сигнала,  для  которого  устанавли-

вается обработчик, заданный параметром 

f

. Здесь 

f

 является ука-

зателем на функцию, которая имеет следующий прототип: 

  void f(int); 

и часто называется 

функцией обработки сигнала

  или  просто 

об-

работчиком  сигнала

.  В  случае  успешного  завершения  функция 

signal

  возвращает  указатель  на  предыдущую  функцию,  установ-

ленную для обработки этого сигнала, а в случае неудачи — зна-
чение, определенное макросом 

SIG_ERR

Для максимальной переносимости программ рекомендуется, что-
бы обработчики асинхронных сигналов использовали только сле-
дующие возможности: 

 

вызовы функции 

signal

, которые успешно завершаются; 

 

присваивание значений переменным типа 

sig_atomic_t

 

возврат управления. 

Тип 

sig_atomic_t

  определен  в  заголовочном  файле  signal.h  и 

предназначен  для  определения  переменных,  значения  которых 


background image

Глава 32. Обработка исключительных ситуаций <signal.h> 

379 

изменяются  атомарными  операциями,  т. е.  такими  операциями, 
которые не прерываются во время своего исполнения. Определе-
ние типа 

sig_atomic_t

 обычно имеет следующий вид: 

  typedef int sig_atomic_t; 

Переменные  типа 

sig_atomic_t

  обычно  имеют  квалификатор 

volatile

  и  используются  для  взаимодействия  между  функцией 

обработки сигнала и программой. 
Обработчик сигнала  может  завершить  свое  исполнение  вызовом 
функций 

abort

exit

 и 

longjmp

В заголовочном файле signal.h определены макросы для следую-
щих стандартных обработчиков сигналов: 

#define SIG_DFL const_адрес  /* обработчик по умолчанию */ 
#define SIG_IGN const_адрес  /* игнорирование сигнала */ 

Выражение 

const_адрес

  задает  адрес  стандартного  обработчика 

для сигнала. Чаще всего эти адреса являются просто целочислен-
ными константами, проверяя значения которых среда исполнения 
выполняет  некоторые  действия  при  вызове  соответствующего 
обработчика. 
В  заголовочном  файле  signal.h  могут  быть  также  определены 
макросы и для других обработчиков сигналов. 

32.3. Возбуждение сигнала 

Для возбуждения сигнала предназначена функция 

raise

, которая 

имеет следующий прототип: 

  int raise(int sig); 

Эта функция возбуждает сигнал, номер которого задан парамет-
ром 

sig

.  В  случае  успешного  завершения  функция  возвращает 

значение 

0

, а в случае неудачи — ненулевое значение. 

Функция 

raise

 работает следующим образом. После возбуждения 

сигнала  управление  передается  функции  обработки  этого  сигна-
ла. Функция 

raise

 не возвращает управление до тех пор, пока не 

завершит  свое  исполнение  функция  обработки  сигнала.  Однако 


background image

Часть III. Стандартная библиотека языка программирования C 

380 

отметим, что после возврата управления из функции 

raise

  пове-

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

SIGFPE

SIGILL

 или 

SIGSEGV

. В этом случае для выхода из функции 

обработки сигнала лучше использовать функцию 

longjmp

При вызове функции обработки сигнала среда исполнения может 
выполнять следующие действия: 

 

блокировать  повторное  возбуждение  сигнала  с  тем  же  номе-
ром,  который  обрабатывает  функция  обработки  сигнала,  до 
передачи управления из этого обработчика; 

 

для обработки повторного сигнала с тем же номером, который 
обрабатывает функция обработки сигнала, вызвать обработчик 
сигнала, заданный по умолчанию; 

 

для  повторного  сигнала 

SIGILL

  среда  исполнения  может  про-

должить обработку предыдущего такого сигнала. 

В листинге 32.1 приведен пример использования функций 

signal

 

и 

raise

Листинг 32.1. Обработка сигнала 

#include<signal.h> 
#include<stdio.h> 
void handler(int sig) 

  printf("Signal handler.\n"); 

int main() 

  void (*f)(int);  /* указатель на обработчик */ 
  /* запоминаем предыдущий обработчик */ 
  f = signal(SIGINT, handler); 
  if(f == SIG_ERR) 
  { 
    printf("Signal set failed.\n");  // неудача 
    return 0; 
  } 
  printf("Raise signal.\n"); 


Смотрите также файлы