Пример: обработчик управляющих сигналов консоли
Пример: обработчик управляющих сигналов консоли
В программе 4.5 организован бесконечный цикл, в котором каждые 5 секунд вызывается функция Веер, подающая звуковой сигнал. Пользователь может завершить выполнение программы, нажав комбинацию клавиш <Ctrl+C> или закрыв консоль. Процедура обработчика выводит на экран сообщение, выжидает 10 секунд, после чего, казалось бы, выполнение программы должно завершиться с возвратом значения TRUE. Однако в действительности основная программа обнаруживает флаг Exit и останавливает процесс. Это демонстрирует параллельную природу выполнения процедуры обработчика; заметьте, что объем выходной информации обработчика сигналов зависит от временных характеристик сигнала. Обработчики управляющих сигналов консоли будут использоваться также в примерах, приводимых в следующих главах.
Обратите внимание на использование макроса WINAPI; он применяется к пользовательским функциям, передаваемым в качестве аргументов функциям Windows, чтобы гарантировать выполнение соответствующих соглашений о вызовах. Этот макрос определен в заголовочном файле Microsoft С WTYPES.Н.
Программа 4.5. Ctrlc: программа обработки сигналов
/* Глава 4. Ctrlc.с */
/* Перехватчик событий консоли. */
#include "EvryThng.h"
static BOOL WINAPI Handler(DWORD CtrlEvent); /* См. WTYPES.H. */
volatile static BOOL Exit = FALSE;
int _tmain(int argc, LPTSTR argv[])
/* Периодическая подача звукового сигнала до поступления сигнала о прекращении выполнения. */
{
/* Добавить обработчик событий. */
if (!SetConsoleCtrlHandler(Handler, TRUE)) ReportError(_T("Ошибка при установке обработчика событий."), 1, TRUE);
while (!Exit) {
Sleep (5000); /* Подача звукового сигнала каждые 5 секунд. */
Веер(1000 /* Частота. */, 250 /* Длительность. */);
}
_tprintf(_T("Прекращение выполнения программы по требованию. "));
return 0;
}
BOOL WINAPI Handler (DWORD CtrlEvent) {
Exit = TRUE;
switch (CntrlEvent) {
/* Увидите ли вы второе сообщения обработчика, зависит от соотношения временных параметров. */
case CTRL_C_EVENT:
_tprintf(_T("Получен сигнал Ctrl-c. Выход из обработчика через 10 секунд. "));
Sleep(4000); /* Уменьшите это значение, чтобы получить другой эффект. */
_tprintf(_T("Выход из обработчика через 6 секунд. "));
Sleep(6000); /* Попробуйте уменьшить и это значение. */
return TRUE; /* TRUE указывает на успешную обработку сигнала. */
case CTRL_CLOSE_EVENT:
_tprintf(_T("Выход из обработчика через 10 секунд. "));
Sleep(4000);
_tprintf(_Т ("Выход из обработчика через 6 секунд. "));
Sleep (6000); /* Попробуйте уменьшить и это значение. */
return TRUE; /* Попробуйте возвратить FALSE. Приводит ли это к изменению поведения программы? */
default:
_tprintf(_T("Событие: %d. Выход из обработчика через 10 секунд. "), CntrlEvent);
Sleep(4000);
_tprintf(_T("Выход из обработчика через 6 секунд. "));
Sleep(6000);
return TRUE;
}
}