Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про Linux: signals, Unix, process, interrupt, event handling, SIGINT

Как работает обработка событий через сигналы?

Вопрос проверяет понимание механизма сигналов (signals) в Unix-подобных системах для асинхронной обработки событий, что необходимо для написания надежных серверных приложений и демонов.

Короткий ответ

Сигналы — это ограниченная форма межпроцессного взаимодействия (IPC) в Unix-подобных системах, уведомляющая процесс о наступлении асинхронного события. Например, нажатие Ctrl+C в терминале отправляет процессу сигнал SIGINT, запрашивая его завершение. Процесс может перехватить большинство сигналов, установив специальную функцию-обработчик (signal handler), которая выполняется асинхронно, прерывая основной поток выполнения. Это позволяет программе корректно реагировать на внешние события, такие как запросы на остановку или изменения состояния системы.

Длинный ответ

Сигналы в Unix-подобных системах (Linux, macOS) — это механизм уведомления процесса о наступлении определенного события. Они являются фундаментальным способом асинхронной обработки прерываний, поступающих от ядра, других процессов или пользователя. Сигнал прерывает нормальное выполнение программы, и если для него зарегистрирован обработчик, управление передается этой функции.

Как это работает

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

Типичные сигналы и их применение

  • SIGINT (2): Посылается при нажатии Ctrl+C в терминале. Обычно используется для graceful shutdown.
  • SIGTERM (15): "Вежливый" запрос на завершение процесса. Позволяет выполнить cleanup.
  • SIGKILL (9): Немедленное уничтожение процесса. Не может быть перехвачен или проигнорирован.
  • SIGSEGV (11): Нарушение сегментации (обращение к невалидной памяти).
  • SIGCHLD (17): Уведомление родительского процесса о завершении дочернего.

Пример кода на C

Вот простой пример программы, которая перехватывает SIGINT и SIGTERM для graceful shutdown:

#include 
#include 
#include 
#include 

volatile sig_atomic_t keep_running = 1;

void handle_signal(int sig) {
    if (sig == SIGINT || sig == SIGTERM) {
        printf("\nПолучен сигнал %d. Завершаем работу...\n", sig);
        keep_running = 0;
    }
}

int main() {
    // Устанавливаем обработчики для SIGINT и SIGTERM
    signal(SIGINT, handle_signal);
    signal(SIGTERM, handle_signal);

    printf("PID: %d. Ожидаю сигналов (Ctrl+C для SIGINT).\n", getpid());

    while (keep_running) {
        // Имитация основной работы программы
        sleep(1);
        printf(".");
        fflush(stdout);
    }

    printf("\nCleanup завершен. Выход.\n");
    return 0;
}

Важные ограничения и best practices

Обработчики сигналов выполняются в контексте прерывания, поэтому они должны быть максимально простыми и быстрыми. Большинство стандартных библиотечных функций (например, printf, malloc) не являются асинхронно-безопасными (async-signal-safe), и их вызов из обработчика может привести к неопределенному поведению. Безопасный подход — установить флаг типа sig_atomic_t внутри обработчика, а основная программа периодически проверяет этот флаг и выполняет тяжелую логику. Для более сложного управления сигналами рекомендуется использовать sigaction вместо устаревшего signal, так как он предоставляет больше контроля над поведением.

Вывод: Сигналы применяются для обработки асинхронных внешних событий в системном программировании, например, для graceful shutdown серверов, обработки ошибок (SIGSEGV) или межпроцессной синхронизации (SIGCHLD). Их стоит использовать, когда требуется реакция на события, генерируемые ядром или другими процессами, но важно помнить об их ограничениях и проектировать обработчики корректно.

  • Аватар

    Python Guru

    Sergey Filichkin

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.

Уровень

  • Рейтинг:

    3

  • Сложность:

    7

Навыки

  • Linux

    Linux

  • C

    C

Ключевые слова

#signals

#Unix

#process

#interrupt

#event handling

#SIGINT

Подпишись на Python Developer в телеграм

  • Аватар

    Python Guru

    Sergey Filichkin

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.