Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
42
Добавлен:
16.04.2013
Размер:
92.67 Кб
Скачать

Использование signal.H

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

#define SIGINT 2 /сигнал прерывания/

#define SIGFPE 8 /исключение с плавающей точкой/

#define SIGABRT 22 /сигнал аварийного завершения/

Система может возбуждать (raise) эти исключения. Например нажатие на клавиатуре клавиш Ctr-C на многих системах генерирует прерывание, обычно убивающее текущий процесс.

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

rize (SIGFPE); //возбужден сигнал исключения с плавающей точкой

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

// вызвать my_abrt (), усли возбуждено SIGABRT

signal (SIGABRT, my_abrt);

// действовать по умолчанию, если возбуждено SIGABRT

signal (SIGABRT, SIG_DFL);

// игнорировать SIGFPE

signal (SIGFPE, SIG_IGN);

Подобные действия называются установкой (installing) обработчика(handler). Они заменяют обычные реакции системы обработчиком, определяемым пользователем.

Используем эти идеи для написания цикла, прерывание которого управляется с клавиатуры. После прерывания обработчик просит пользователя решить, должна ли программа продолжить выполнени.

В файле signal.Cpp

//Прерывания, обрабатываемые с помощью signal.h

#include <signal.h>

#include <time.h>

#include <iostream.h>

#include <stdlib.h>

void cntrl_c_handler (int sig);

inline double clk_psec()

{

return static_cast<double>(clock ())/CLOCKS_PER_SEC;

}

int main()

{

int i = 0, j;

cout << считаем до j миллионов, введите j: “;

cin >> j;

j  = 1000000;

signal (SIGINT, cntrl_c_handler);

cout << clk_psec() << “начальное время \n”;

while (1) {

++i;

if (i>j) {

cout << clk_psec() << конец цикла \n;

cout << “ЦИКЛ ИСПОЛНЕН” <<j/1000000

<<”МИЛЛИОН РАЗ” << endl;

raise (SIGINT);

cout << “\nВведите j: ”;

cin >> j;

j =1000000;

I = 0;

cout << clk_psec() << начало цикла \n;

}

}

}

}

void cntrl_c_handler (int sig)

{

char c;

cout << “ПРЕРЫВАНИЕ”;

cout << “\nвведите Д для продолжения:”;

cin >> c:

if (c = =’Д’)

signal (SIGINT, cntrl_c_handler);

else

exit (0);

}

Разбор программы signal

  • signal (SIGINT, cntrl_c_handler);

Обработчик функции связан с прерыванием SIGINT. При выявлении следующего прерывания система вызывает cntrl_c_handler вместо системного действия по умолчанию.

  • while (1) {

++i;

if (i > j) {

….

raise (SIGINT);

Сигнал прерывания возбуждается явным вызовом; cntrl_c_handler() вызывается неявно.

  • void cntrl_c_handler (int sig)

Эта процедура обрабатывает исключение SIGINT.

  • cout << “ПРЕРЫВАНИЕ”;

cout << ”\nвведите Д для продолжения :”;

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

  • if (c = = ‘Д’)

signal (SIGINT, cntrl_c_handler);

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

  • else

exit (0);

Для завершения вызывается функция exit () из stdlib.h.

Применим эту технику обработки исключений для типа vect (см.раздел 7.7, «Перегрузка операторов индексирования и присваивания», на стр.203). Начнем с замены проверки утверждений на условия, которые возбуждают определенные пользователем сигналы.

Соседние файлы в папке Тельминов (мб)