Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> Язык C

Освоение обработки сигналов в C++: безопасное управление прерываниями и корректное завершение программы

Сигналы — это прерывания, которые операционная система передает процессу. Они могут привести к преждевременному завершению программы. Например, нажатие Ctrl+C в UNIX, Linux, macOS или Windows генерирует сигнал прерывания.

Не все сигналы можно перехватить, но существует список сигналов, которые программа может обрабатывать, выполняя соответствующие действия. Эти сигналы определены в заголовочном файле C++ <csignal>.

№Сигнал и описание
1SIGABRT — аварийное завершение программы, например, вызов функции abort().
2SIGFPE — ошибочная арифметическая операция, такая как деление на ноль или переполнение.
3SIGILL — обнаружение недопустимой инструкции.
4SIGINT — получение интерактивного сигнала внимания (обычно Ctrl+C).
5SIGSEGV — недопустимый доступ к памяти.
6SIGTERM — запрос на завершение программы.

Функция signal()

Библиотека обработки сигналов C++ предоставляет функцию signal для перехвата непредвиденных событий. Её синтаксис:

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

Проще говоря, функция принимает два аргумента: номер сигнала (целое число) и указатель на функцию-обработчик.

Рассмотрим пример перехвата сигнала SIGINT с помощью signal(). Любой сигнал, который вы хотите отловить, нужно зарегистрировать, связав его с обработчиком.

#include <iostream>
#include <csignal>
using namespace std;

void signalHandler(int signum) {
    cout << "Interrupt signal (" << signum << ") received.\n";
    // очистка и закрытие ресурсов
    exit(signum);
}

int main() {
    // регистрация SIGINT и обработчика
    signal(SIGINT, signalHandler);
    while (true) {
        cout << "Going to sleep...." << endl;
        sleep(1);
    }
    return 0;
}

При компиляции и запуске программа будет выводить "Going to sleep...." каждую секунду. Нажмите Ctrl+C, чтобы прервать выполнение — программа перехватит сигнал и завершится с сообщением:

Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.

Функция raise()

Сигналы можно генерировать программно с помощью функции raise(), которая принимает номер сигнала:

int raise(int sig);

Аргумент sig может быть одним из: SIGINT, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGTERM, SIGHUP.

Пример генерации сигнала внутри программы:

#include <iostream>
#include <csignal>
using namespace std;

void signalHandler(int signum) {
    cout << "Interrupt signal (" << signum << ") received.\n";
    exit(signum);
}

int main() {
    int i = 0;
    signal(SIGINT, signalHandler);
    while (++i) {
        cout << "Going to sleep...." << endl;
        if (i == 3) {
            raise(SIGINT);
        }
        sleep(1);
    }
    return 0;
}

Программа автоматически завершится после третьей итерации с выводом:

Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.

Язык C

  1. Понимание типов данных C++: основы, модификаторы и лучшие практики
  2. Освоение операторов C++: полное руководство с практическими примерами
  3. Комментарии в C++: лучшие практики для читаемого и поддерживаемого кода
  4. Шаблоны классов в C++: практическое руководство
  5. Работа с файлами в C: мастерство ввода-вывода с fopen, fprintf, fread и fseek
  6. Обработка исключений в C++: практические примеры try, catch, throw
  7. Обработка ошибок в C: лучшие практики и техники
  8. Язык программирования C++: обзор и ключевые особенности
  9. Константы и литералы в C++: типы, синтаксис и лучшие практики
  10. Полное руководство по операторам C++: типы, использование и лучшие практики