TGViewer
LinuxCamp | DevOps LinuxCamp | DevOps @linuxcamp_tg · 13.6K subscribers
Post #135 10.1K
Перехват и обработка сигналов

Обработчик сигнала — функция, написанная программистом и выполняющая нужные действия при получении сигнала.

Например, для оболочки может быть определен обработчик сигнала SIGINT, который генерируется комбинацией Ctrl+C. Он заставляет оболочку прекратить выполнение текущей задачи и вернуть управление в основной цикл так, что пользователь опять видит приглашение на ввод команды:


parallels@ubuntu-linux-22-04-02:~$ ./app
App executes...
parallels@ubuntu-linux-22-04-02:~$


И так, существует два способа перехвата сигнала: signal() и sigaction(). Функция signal() реализована в glibc как библиотечная, поверх системного вызова sigaction().

Давайте напишем мини-программу, которая никогда не завершается и все время что-то там выполняет:


#include "stdio.h"

int main()
{
while (1) {
printf("Do some work, pid = %d\n", getpid());
sleep(1);
}

return 0;
}


Прям никогда не завершается?)) Еще как, нам всего-то стоит нажать Ctrl+C:


$ ./prog
Do some work, pid = 675989
Do some work, pid = 675989
^C


Что произошло? Оболочка и ее дочерний процесс (675989) получили сигнал SIGINT. Bash, т.к. отработал перехват, не завершил выполнение, а вот наша программа потухла, т.к. ничего в ней не переопределяет дефолтного поведения. Давайте внесем некоторые правки и кое-что добавим:


#include "stdio.h"
#include "unistd.h"
#include "signal.h"

void handler (int num) {
write(STDOUT_FILENO, "I won't die!\n", 13);
}
int main()
{
signal(SIGINT, handler);
while (1) {
printf("Do some work, pid = %d\n", getpid());
sleep(1);
}

return 0;
}



$ ./prog
Do some work, pid = 681049
Do some work, pid = 681049
Do some work, pid = 681049
^CI won't die!
Do some work, pid = 681049
^CI won't die!


Если какой-то хитрый разраб такое провернет, знайте, что есть еще сигналы, на которые прога завершается. Отправим SIGTERM и, если на него не стоит обработчиков, продолжим спокойно работать:


$ kill -TERM 681049
Do some work, pid = 681049
Terminated


Есть, кста, 1 сигнал, на который невозможно повесить обработчик - SIGKILL. Так устроено, что этот сигнал является для процесса ПРИКАЗОМ, нежели просьбой:


$ kill -KILL 683152


Обратите внимание, что невозможно установить перехват сигнала таким образом, чтобы, без явного указания, он завершал процесс. Максимум, как мы можем приблизиться к этому, — прописать в обработчике одну из двух функций: exit() или abort().

Функция abort() генерирует для процесса сигнал SIGABRT, который приводит к сбросу дампа и завершению. Даже если на SIGABRT повесить обработчик, программа все равно завершится - особенность реализации.

Linux++ | IT-Образование
  • 👍 34
  • 🔥 10
  • ❤ 3
  • ❤‍🔥 2
More from @linuxcamp_tg
  1. Sep 28, 2026Проекту GNU вчера исполнилось 43 года 1983 год: Ричард Столлман объявил планы разработать…
  2. Sep 25, 2026Linux будет работать на ноутах с Snapdragon X2. Qualcomm добавляет полноценную поддержку L…
  3. Sep 24, 2026Так все по делу)) Советует же самый быстрый фикс LinuxCamp | #memes
  4. Sep 23, 2026Планы на 3 октября — прийти на RWB Infra x Security Meetup Мы направим прожекторы на инфра…
  5. Sep 22, 2026Ещё одна рекордная неделя для AI-разработки в Linux. На прошлой неделе в ядро попало 1 634…
  6. Sep 17, 2026Открыл плейлист, а как выйти - непонятно 😁 LinuxCamp | #memes
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →