Сигналы
Сигналы являются способом передачи от одного процесса другому или от ядра операционной системы какому-либо процессу уведомления о возникновении определенного события. Сигналы можно рассматривать как простейшую форму межпроцессного взаимодействия. В то же время сигналы больше напоминают программные прерывания, — средство, с помощью которого нормальное выполнение процесса может быть прервано. Например, если процесс производит деление на 0, ядро посылает ему сигнал SIGFPE, а при нажатии клавиш прерывания, обычно Del> или Ctrl>+C>, текущему процессу посылается сигнал SIGINT.
Для отправления сигнала служит команда kill(1):
kill sig_no pid
где sig_nо — номер или символическое название сигнала, a pid — идентификатор процесса, которому посылается сигнал. Администратор системы может посылать сигналы любым процессам, обычный же пользователь может посылать сигналы только процессам, владельцем которых он является (реальный и эффективный идентификаторы процесса должны совпадать с идентификатором пользователя[10]). Например, чтобы послать процессу, который вы только что запустили в фоновом режиме, сигнал завершения выполнения SIGTERM, можно воспользоваться командой:
Запустим программу в фоновом режиме
По умолчанию команда kill(1) посылает сигнал SIGTERM; переменная $! содержит PID последнего процесса, запущенного в фоновом режиме
При получении сигнала процесс имеет три варианта действий для выбора:
1. Он может игнорировать сигнал. Не следует игнорировать сигналы, вызванные аппаратной частью, например, при делении на 0 или ссылке на недопустимые области памяти, так как дальнейшие результаты в отношении данного процесса непредсказуемы.
2. Процесс может потребовать действия по умолчанию. Как ни печально, обычно это сводится к завершению выполнения процесса.
3. Наконец, процесс может перехватить сигнал и самостоятельно обработать его. Например, перехват сигнала SIGINT позволит процессу удалить созданные им временные файлы, короче, достойно подготовиться к «смерти». Следует иметь в виду, что сигналы SIGKILL и SIGSTOP нельзя ни перехватить, ни игнорировать.
По умолчанию команда kill(1) посылает сигнал с номером 15 — SIGTERM[11], действие по умолчанию для которого — завершение выполнения процесса, получившего сигнал.
Иногда процесс продолжает существовать и после отправления сигнала SIGTERM. В этом случае можно применить более жесткое средство — послать процессу сигнал SIGKILL с номером (9), — поскольку этот сигнал нельзя ни перехватить, ни игнорировать:
$ kill -9 pid
Однако возможны ситуации, когда процесс не исчезает и в этом случае. Это может произойти для следующих процессов:
? Процессы-зомби. Фактически процесса как такового не существует, осталась лишь запись в системной таблице процессов, поэтому удалить его можно только перезапуском операционной системы. Зомби в небольших количествах не представляют опасности, однако если их много, это может привести к переполнению таблицы процессов.
? Процессы, ожидающие недоступные ресурсы NFS (Network File System), например, записывающие данные в файл файловой системы удаленного компьютера, отключившегося от сети. Эту ситуацию можно преодолеть, послав процессу сигнал SIGINT или SIGQUIT.
? Процессы, ожидающие завершения операции с устройством, например, перемотки магнитной ленты.
Сигналы могут не только использоваться для завершения выполнения но и иметь специфическое для приложения (обычно для системных демонов) значение (естественно, это не относится к сигналам SIGKILL и SIGSTOP). Например, отправление сигнала SIGHUP серверу имен DNS named(1M) вызовет считывание базы данных с диска. Для других приложений могут быть определены другие сигналы и соответствующие им значения.
Более подробно сигналы мы рассмотрим в главах 2 и 3.
Данный текст является ознакомительным фрагментом.
Продолжение на ЛитРес
Читайте также
Глава 10 Сигналы
Глава 10 Сигналы Данная глава освещает все подробности сигналов, важную, но сложную часть GNU/Linux
12.3. Доступные сигналы
12.3. Доступные сигналы Linux предоставляет в распоряжение процессов сравнительно немного сигналов, и все они собраны в табл. 12.1.Таблица 12.1. Сигналы Сигнал Описание Действие по умолчанию SIGABRT Доставляется вызовом abort(). Прервать, сбросить дамп SIGALRM Истек срок действия
Сигналы
Сигналы Сигналы являются способом передачи от одного процесса другому или от ядра операционной системы какому-либо процессу уведомления о возникновении определенного события. Сигналы можно рассматривать как простейшую форму межпроцессного взаимодействия. В то же
Надежные сигналы
Надежные сигналы Стандарт POSIX. 1 определил новый набор функций управления сигналами. основанный на интерфейсе 4.2BSD UNIX и лишенный рассмотренных выше недостатков.Модель сигналов, предложенная POSIX, основана на понятии набора сигналов (signal set), описываемого переменной типа
Сигналы
Сигналы В некотором смысле сигналы обеспечивают простейшую форму межпроцессного взаимодействия, позволяя уведомлять процесс или группу процессов о наступлении некоторого события. Мы уже рассмотрели в предыдущих главах сигналы с точки зрения пользователя и
7.2 СИГНАЛЫ
7.2 СИГНАЛЫ Сигналы сообщают процессам о возникновении асинхронных событий. Посылка сигналов производится процессами — друг другу, с помощью функции kill, — или ядром. В версии V (вторая редакция) системы UNIX существуют 19 различных сигналов, которые можно классифицировать
5.8.2. Сигналы
5.8.2. Сигналы Демон syslogd реагирует на следующие сигналы: SYGTERM, SIGINT, SIGQUIT, SIGHUP, SIGUSR1, SIGCHLD. Реакция демона на сигналы описана в табл. 5.8.Реакция демона на сигналы Таблица 5.8 Сигнал Реакция SIGTERM Завершает работу демона SIGINT, SIGQUIT Завершает работу демона, если выключена отладка
3.3.2. Сигналы
3.3.2. Сигналы Механизм сигналов — это средство, позволяющее сообщать процессам о некоторых событиях в системе, а процессу-получателю — должным образом на эти сообщения реагировать. Послать сигнал может сам процесс (например, при попытке деления на ноль), ядро (при сбое
27.3.10. Сигналы и сокеты
27.3.10. Сигналы и сокеты С сокетами связаны три сигнала:? SIGIO — сокет готов к вводу/выводу. Сигнал посылается процессу, который связан с сокетом;? SIGURG — сокет получил экспресс-данные (мы их использовать не будем, поэтому особо останавливаться на них нет смысла);? SIGPIPE — запись
7.2.6.2. Сигналы
7.2.6.2. Сигналы Самый простой и грубый способ сообщения между двумя процессами на одной машине заключается в том, что один из них отправляет другому какой-либо сигнал (signal). Сигналы в операционной системе Unix представляют собой форму программного прерывания. Каждый сигнал
7.2.6.2. Сигналы
7.2.6.2. Сигналы Самый простой и грубый способ сообщения между двумя процессами на одной машине заключается в том, что один из них отправляет другому какой-либо сигнал (signal). Сигналы в операционной системе Unix представляют собой форму программного прерывания. Каждый сигнал
3.3. Сигналы
3.3. Сигналы Сигналы — это механизм связи между процессами в Linux. Данная тема очень обширна, поэтому здесь мы рассмотрим лишь наиболее важные сигналы и методики управления процессами.Сигнал представляет собой специальное сообщение, посылаемое процессу. Сигналы являются
Какие сигналы нельзя перехватить в linux
В вашей системе есть страница man, на которой перечислены все имеющиеся сигналы, но доступ к этой странице происходит по-разному в зависимости от того, какая у вас операционная систем. В большинстве систем Linux страницу можно открыть с помощью команды man 7 signal. Если возникнут проблемы, то найдите точное месторасположение страницы man с помощью команды
man -k signal | grep list
apropos signal | grep list
Имена сигналов можно получить с помощью команды kill -l .
Сигналы в вашей командной оболочке Bash
Когда отсутствуют какие-либо команды trap, интерактивная оболочка Bash игнорирует сигналы SIGTERM и SIGQUIT. Сигнал SIGINT перехватывается и обрабатывается, и если осуществляется управление заданиями, то также игнорируются сигналы SIGTTIN, SIGTTOU и SIGTSTP. Если эти сигналы поступают от клавиатуры, то команды, участвующие в подстановке команд, также игнорируют эти сигналы.
По сигналу SIGHUP по умолчанию происходит выход из командной оболочки. Интерактивная оболочка отправит сигнал SIGHUP всем заданиям, работающим или остановленным; если вы хотите отменить такое действие для конкретного процесса, которое задается по умолчанию, смотрите документацию по встроенной команде disown. Во встроенной команде shopt укажите параметр huponexit для уничтожения всех заданий, принимающих сигнал SIGHUP.
Посылаем сигнал в командной оболочке
В оболочке Bash можно посылать следующие сигналы:
Таблица 12.1. Управляющие сигналы в Bash
Сигнал прерывания, отправляет сигнал SIGINT заданию, работающему в приоритетном режиме.
Сигнал задержанной приостановки. Вызывает остановку работающего процесса, когда он попытается прочитать из терминала входные данные. Управление возвращается в командную оболочку, причем пользовательский процесс может оставаться приоритетным, фоновым или может быть уничтожен. Задержанную приостановку можно использовать только в тех операционных системах, где эта функция поддерживается.
Сигнал приостановки, посылается SIGTSTP в работающую программу, что ведет к остановке программы и возвращению управления в командную оболочку.
Проверьте настройки вашего терминала stty. Приостановка и возобновление выдачи выходных данных отключена, если вы используете эмуляцию «современных» терминалов. Стандартный терминал xterm по умолчанию поддерживает Ctrl+S и Ctrl+Q.
Использование сигналов с функцией kill
В большинстве современных командных оболочек, к которым относится Bash, есть встроенная функция kill. В Bash в качестве параметров можно указывать имена и номера сигналов, а аргументами могут быть задания или идентификаторы процессов. Состояние кода возврата можно получить с помощью параметра -l : ноль, если успешно отправлен хотя бы один сигнал, и не ноль, если произошла ошибка.
Когда используется команда kill из /usr/bin в вашей системе, то в команде могут быть дополнительные возможности, позволяющие уничтожать процессы с идентификатором не вашего, а другого пользователя, и указывать процессы по именам, точно также, как в pgrep и pkill.
Если ничего не задано, то оба варианта команды kill посылают сигнал TERM.
Это список наиболее распространенных сигналов:
Таблица 12.2. Наиболее распространенные сигналы
Прерывание с клавиатуры
Сигналы SIGKILL и SIGSTOP нельзя перехватывать, блокировать или игнорировать.
Когда уничтожается процесс или серия процессов, разумно начать с попытки использовать менее опасный сигнал SIGTERM. Таким образом, программам, которым важно правильное их завершение, предоставляется шанс следовать процедурам, которые создаются для случаев, когда программы получают сигнал SIGTERM, например, процедурам уборки мусора и закрытия открытых файлов. Если вы посылаете в процесс сигнал SIGKILL, все шансы сделать в этом процессе аккуратную уборку мусора и остановку могут быть потеряны и это может привести к плачевным последствиям.
Но если чистое завершение не работает, единственным способом остаются сигналы INT или KILL. Например, когда процесс не уничтожается с помощью нажатия клавиш Ctrl+C, то лучше использовать kill -9 и указать идентификатор процесса:
maud: ~> ps -ef | grep stuck_process maud 5607 2214 0 20:05 pts/5 00:00:02 stuck_process maud: ~> kill -9 5607 maud: ~> ps -ef | grep stuck_process maud 5614 2214 0 20:15 pts/5 00:00:00 grep stuck_process [1]+ Killed stuck_process
Когда процесс запускает несколько экземпляров, проще воспользоваться командой killall. В ней используются те же самые параметры, как и в команде kill, но она применяется ко всем экземплярам данного процесса. Испытайте эту команду прежде, чем ей воспользоваться на практике, поскольку в некоторых коммерческих версиях UNIX она может работать не так, как ожидается.
| Предыдущий раздел: | Оглавление | Следующий раздел: |
| Подводим итоги главы 11 | Команды Trap |
Какие сигналы перехватывать обязательно?
Теперь задача — перехватывать сигналы, т.к. надо завершится мягко, что-то сохранить, а не падать трупом.
// SIGKILL - Не перехватывается, не игнорится, не обрабатывается, сразу труп // SIGSTOP - Не перехватывается, не игнорится, не обрабатывается, просто стоп, freeze чтоли? // SIGTSTP - Это rerise(?) от VSUSP (Ctrl+Z) может быть блокирован, перехвачен, игнорирован // SIGCONT - Продолжить после стопа, но нет смысла вешать обработчик // SIGTERM - Может быть блокирован, перехвачен, игнорирован // SIGINT - Это Ctrl+C // SIGQUIT - Ctrl+\ какой-то дамп, я так понял отладочный коредамп // SIGHUP - Отвалился терминал? а как потом вернуться в терминал если он отвалился? // SIGTTOU - Попытка писать в терминал из фона // SIGPIPE - Брокнутые FIFO или отвалился сокет // SIGLOST - Потеряно соединение с сервером(?) с любым ли? // SIGXCPU - Превышен лимит процессорного времени // SIGXFSZ - Превышен лимит величины размера файла (если к файлу то м.б. ограничение для fat32, а как насчет дисковой квоты?) // SIGINFO - Кагдила
Какие еще сигналы надо учесть?

deep-purple ★★★★★
28.12.14 06:49:16 MSK
Обычно перехватывают SIGTERM (это выход) и SIGHUP. SIGHUP обычно служит для рестарта и перечитывания конфига.
niemand
( 28.12.14 07:55:56 MSK )
Ответ на: комментарий от niemand 28.12.14 07:55:56 MSK

Глянь на первый пост, я дописал еще ))
Как видишь — этого мало, кроме сигтерма есть еще несколько, и если ты будешь ловить только сигтерм, то профукаешь остальные.
deep-purple ★★★★★
( 28.12.14 08:28:15 MSK ) автор топика

E ★★★
( 28.12.14 09:08:11 MSK )
Ответ на: комментарий от E 28.12.14 09:08:11 MSK

Не забыл, предполагается что на ввод ничего не будет слушаться.
deep-purple ★★★★★
( 28.12.14 09:30:05 MSK ) автор топика
Ответ на: комментарий от deep-purple 28.12.14 08:28:15 MSK
Можешь взять пример из гугля.
Обработчики там только на 3 сигналах: 2 мной названных и SIGINT. Кое-что там ещё заблокированно (это тебе решать)
Ты можешь обрабатовать и больше (хоть SIGILL или SIGSEGV), но обычно этих 3 хватает (всё зависит от того, что делает твоя программа)
niemand
( 28.12.14 09:54:27 MSK )
SIGINT, SIGTERM, SIGPIPE, желательно SIGHUP.
mashina ★★★★★
( 28.12.14 10:47:28 MSK )

Отвалился терминал? а как потом вернуться в терминал если он отвалился?
Демон обычно сам отключается от терминала.
AptGet ★★★
( 28.12.14 12:11:01 MSK )
Ответ на: комментарий от AptGet 28.12.14 12:11:01 MSK

Это если демон. А если ты зашел по ssh, запустил прилагу, и ssh отвалился на твоей стороне?
$ ./prog $ Ctrl+Z $ bg
Как отловить в прилаге что её в фон кинули? Через этсамый SIGTTOU?
deep-purple ★★★★★
( 28.12.14 12:45:45 MSK ) автор топика

SIGINT/SIGTERM обязательно, остальное по вкусу.
post-factum ★★★★★
( 30.12.14 01:36:29 MSK )
Лет 15 назад забил болт на весь этот зоопарк с сигналами, терминалами и другими std(in/out/err) и демонизациями. Пишу все сервера как обыкновенное консольное приложение. Перехватываю только SIGHUP (по нему переоткрываю логи для ротейтов/перечитываю конфиги) и SIGINT по нему корректно завершаюсь. Проблем никогда небыло (главное ввод вывод делать так чтоб всяких sigpipe не возникало) — зато процесс отладки / управления упростился значительно (в любой момент запустил в консоле, виден весь stdout и stderr Ctrl+C — завершился). При переносе в продакшен деманизирую приложение по средством шела прямо из стартап скрипта — в нем же стоит и вачдог на баше (который просто делает waitpid и смотрит по какой причине сервер завершился — если что респавнит и шлет почту).
Конечно бывают спецефические случаи когда нужно чтото обработать дополнительно, или вообще перейти в отдельную терминальную группу — но у меня такие задачи возникали только в институте 🙂
PS. возможно на некоторых *bsd/unix системах могут быть проблемы, я в основном работаю с linux. Пару раз запускал свой софт на FreeBSD, Solaris, Open Solaris, AIX — там в принципе все тоже работало нормально, только приходилось немного править стартап/ватчдог скрипты.
PS.PS Подбешивают демоны которых нельзя запустить в фореграунде (по умолчанию демонизируются и нету ключика аля —foregraund). Если вдруг сломался и не запускается/не работает при этом в логах тишина — то ни подебажить нормально, ни stdin/stderr и если нужно на вачдога посадить — то тоже приходится костыли делать.
zaz ★★★★
( 30.12.14 02:45:48 MSK )
Ответ на: комментарий от zaz 30.12.14 02:45:48 MSK

Ды, я вот хочу вообще шоп сам не умел в демона. Если надо будет, то а-ля 1>> /dev/null 2>> /dev/null &
Хз насколько это нормально..
Но тут вопрос что если он в бг попадет при обычном запуске, то будет продолжать гадить в кансоль свои stdout/stderr мессаги. Как в ём определять что его отправили в бг (не суспенд) (чтоб перестал гадить) и как потом понять что подняли в фг (чтоб продолжил)?
deep-purple ★★★★★
( 30.12.14 03:20:33 MSK ) автор топика
Ответ на: комментарий от deep-purple 30.12.14 03:20:33 MSK
Если честно никогда таким не заморачивался. Но могу предположить что это может быть зависимо от конкретного шела (поскольку для ОС нет такого понятия как фореграунд и бекграунд, это больше шел всем этим заведует). Также могу предположить что смотреть нужно в сторону терминальных груп (tcgetpgrp) — шел должен держать фореграунд и бекграунд процессы в различных терминальных группах (тоесть bg/fg должны переводить процесс с одной группы в другую). Насщет сигналов не уверен но я бы посмотрел в сторону SIGTTIN/SIGTTOU
zaz ★★★★
( 30.12.14 03:36:58 MSK )
Ответ на: комментарий от deep-purple 30.12.14 03:20:33 MSK

Как в ём определять что его отправили в бг
не нужно так делать. Если нужно отправить в bg, и чтоб не срал, то перенаправь вывод и отправь в bg. Это не задача самого приложения.
К тому же, удобно отправлять в bg, а сообщения перенаправить в лог-файл.
перехватывать сигналы, т.к. надо завершится мягко, что-то сохранить, а не падать трупом.
Функция обработчик сигналов
Данная функция вызывается, когда процесс (или нить) получает неблокируемый сигнал. Дефолтный обработчик завершает наш процесс (нить). Но мы можем сами определить обработчики для интересующих нас сигналов. Следует очень осторожно относится к написанию обработчика сигналов, это не просто функция, выполняющаяся по коллбеку, происходит прерывание текущего потока выполнения без какой либо подготовительной работы, таким образом глобальные объекты могут находится в неконсистентном состоянии. Автор не берется приводить свод правил, так как сам их не знает, и призывает последовать совету Kobolog (надеюсь он не против, что я ссылаюсь на него) и изучить хотя бы вот этот материал FAQ.
void hdl(int sig)
Установить новый обработчик сигнала можно двумя функциями
sighandler_t signal(int signum, sighandler_t handler);
- функция не блокирует получение других сигналов пока выполняется текущий обработчик, он будет прерван и начнет выполняться новый обработчик
- после первого получения сигнала (для которого мы установили свой обработчик), его обработчик будет сброшен на SIG_DFL
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
- sa_handler — аналогичен sighandler_t в функции signal
- sa_mask — маска сигналов который будут блокированы пока выполняется наш обработчик. + по дефолту блокируется и сам полученный сигнал
- sa_flags — позволяет задать дополнительные действия при обработке сигнала о которых лучше почитать тут
struct sigaction act; memset(&act, 0, sizeof(act)); act.sa_handler = hdl; sigset_t set; sigemptyset(&set); sigaddset(&set, SIGUSR1); sigaddset(&set, SIGUSR2); act.sa_mask = set; sigaction(SIGUSR1, &act, 0); sigaction(SIGUSR2, &act, 0);
Здесь мы установили наш обработчик для сигналов SIGUSR1 и SUGUSR2, а также указали, что необходимо блокировать эти же сигналы пока выполняется обработчик.
С обработчиком сигналов есть один не очень удобный момент, он устанавливается на весь процесс и все порожденные нити сразу. Мы не имеет возможность для каждой нити установить свой обработчик сигналов.
Но при этом следует понимать что когда сигнал адресуется процессу, обработчик вызывается именно для главной нити (представляющей процесс). Если же сигнал адресуется для нити, то обработчик вызывается из контекста этой нити. См пример 1.
Блокирование сигналов
Для того, чтобы заблокировать некоторый сигналы для процесса, необходимо добавить их в маску сигналов данного процесса. Для этого используется функция
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
Мы можем к уже существующей маске сигналов добавить новые сигналы (SIG_BLOCK), можем из этой маски убрать часть сигналов (SIG_UNBLOCK), а так же установить полностью нашу маску сигналов (SIG_SETMASK).
Для работы с маской сигналов внутри нити используется функция
int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset);
которая позволяет сделать все тоже, но уже для каждой нити в отдельности.
Невозможно заблокировать сигналы SIGKILL или SIGSTOP при помощи этих функций. Попытки это сделать будут игнорироваться.
sigwait
Данная функция позволяет приостановить выполнении процесса (или нити) до получения нужного сигнала (или одного из маски сигналов). Особенностью этой функции является то, что при получении сигнала не будет вызвана функции обработчик сигнала. См. пример 2.
Посыл сигнала
Для того, чтобы послать сигнал процессу можно использовать две функции
int kill(pid_t pid, int sig); int raise(int sig);
С первой все понятно. Вторая нужна для того, чтобы послать сигнал самому себе, и по сути равносильна kill(getpid(), signal). Функция getpid() возвращает PID текущего процесса.
Для того, чтобы послать сигнал отдельной нити, используется функция
int pthread_kill(pthread_t thread, int sig);
Пример использования сигналов
Все, что я описал выше, не дает ответа на вопрос «Зачем мне использовать сигналы». Теперь я хотел бы привести реальный пример использования сигналов и где без них попросту не обойтись.
Представьте, что вы хотите читать или писать какие-то данные в какое то устройство, но это может привести к блокированию. Ну например, чтение в случае работы с сокетами. Или может быть запись в пайп. Вы можете вынести это в отдельный поток, чтобы не блокировать основную работу. Но что делать когда вам нужно завершить приложение? Как корректно прервать блокирующую операцию IO? Можно было бы задавать таймаут, но это не очень хорошее решение. Для этого есть более удобные средства: функции pselect и ppoll. Разница между ними исключительно в юзабельности, поведение у них одинаковое. В первую очередь эти функции нужны для мультиплексирования работы с IO (select/poll). Префикс ‘p’ в начале функции указывает на то, что данная функция может быть корректно прервана сигналом.
Итак, сформулируем требование:
Необходимо разработать приложение, открывающее сокет (для простоты UDP) и выполняющее в потоке операцию чтения. Данное приложение должно корректно без задержек завершаться по требованию пользователя.
Функция треда выглядит вот так
void* blocking_read(void* arg) < if(stop) < // не успели стартовать, а нас уже прикрыли ? std::cout // Блокируем сигнал SIGINT sigset_t set, orig; sigemptyset(&set); sigaddset(&set, SIGINT); sigemptyset(&orig); pthread_sigmask(SIG_BLOCK, &set, &orig); if(stop) < // пока мы устанавливали блокировку сигнала он уже произошол // возвращаем все как было и выходим std::cout // Здесь нас не могут прервать сигналом SIGINT std::cout // Мы либо считали данные, либо произошла какаято ошибка. Но мы не получали // сигнала о завершении работы и продолжаем работать "по плану" close(sockfd); pthread_exit((void *)0); >
- проверяем, что пока стартовал тред его еще не пожелали завершить
- блокируем завершающий сигнал
- проверяем, что пока блокировали, нас не пожелали завершить
- вызываем ppoll передавая в качестве последнего параметра маску сигналов по которой ждется сигнал
- после выхода из ppoll проверяем что вышли не из за сигнала о завершении
int main()
Устанавливаем наш обработчик для SIGINT, и когда нужно завершить дочерний поток шлем ему этот сигнал.
Полный листинг см. пример 3.
На мой взгляд, недостатком данного способа является то, что в случае нескольких потоков мы можем завершить их только все сразу. Нет возможности устанавливать свой обработчик сигналов для каждого треда. Таким образом, нет возможности реализовать полноценное межпоточное взаимодействие через сигналы. Linux way это не предусматривает.
PS. Исходные коды разместил на сервисе PasteBin (ссылку не даю, а то еще за рекламу посчитают).
PPS. Прошу простить за обилие ошибок. Язык, слабая моя сторона. Спасибо, всем кто помог их исправить.
Данная статья не претендует на полное (и глубокое) описание работы с сигналами и нацелена в первую очередь на тех, кто до этого момента не сталкивались с понятием «сигнал». Для более глубоко понимания работы сигналов автор призывает обратиться в более компетентные источники и ознакомиться с конструктивной критикой в комментариях.