Какие сигналы нельзя перехватить в linux
Главное отличие сигналов от других средств взаимодействия между процессами заключается в том, что их обработка программой обычно происходит сразу же после поступления сигнала (или не происходит вообще), независимо от того, что программа делает в данный момент. Сигнал прерывает нормальный порядок выполнения инструкций в программе и передает управление специальной функции – обработчику сигнала. Если обработка сигнала не приводит к завершению процесса, то по выходе из функции-обработчика выполнение процесса возобновляется с той точки, в которой оно было прервано. У программ также есть возможность приостановить обработку поступающих сигналов временно, на период выполнения какой-либо важной операции. В традиционной терминологии приостановка получения определенных сигналов называется блокированием. Если для поступившего сигнала было установлено блокирование, сигнал будет передан программе, как только она разблокирует данный тип сигналов. Этим блокирование отличается от игнорирования сигнала, при котором сигналы соответствующего типа никогда не передаются программе. Следует помнить, что не все сигналы могут быть проигнорированы. Например, при получении программой сигнала принудительного завершения SIGKILL система ничего не сообщает программе, а просто прекращает ее работу. Таким образом, преимущество сигналов перед другими средствами взаимодействия с программой заключается в том, что посылать программе сигналы можно в любой момент ее работы, не дожидаясь наступления каких-то особых условий. Источником сигналов может быть как сам операционная система, так и другие программы пользователя. Если вам показалось, что сигналы похожи на прерывания, то вы совершенно правы. Для реализации сигналов действительно используются программные прерывания.
Номерам сигналов соответствуют константы, определенные в файле <signal.h>. Имена всех этих констант начинаются с префикса SIG, за которыми следует сокращенное название сигнала. Стандарт POSIX определяет две группы сигналов – «классические» сигналы Unix и сигналы реального времени. В отличие от классических сигналов сигналы реального времени всегда буферизуются, так что программа получит все посланные ей сигналы. В этой статье мы рассмотрим только классические сигналы Unix, каковых в Linux насчитывается 31. Этим сигналам назначены номера с 1 до 31 (номер 0, так называемый null-сигнал имеет особый смысл). Полный список сигналов можно получить из заголовочного файла signal.h. Мы рассмотрим несколько наиболее интересных сигналов.
Сигнал SIGHUP (номер 1) изначально был предназначен для того, чтобы информировать программу о потере связи с управляющим терминалом (терминалы часто подключались к системе с помощью модемов, так что название сигнала происходит от hung up – повесить трубку). Сигнал SIGHUP посылается приложению так же и в том случае, если процесс-лидер сессии завершил свою работу. Многие программы-демоны, у которых нет лидера сессии, так же обрабатывают этот сигнал. В ответ на получение SIGHUP демон обычно перезапускается (или просто повторно читает файл конфигурации). По умолчанию программа, получившая этот сигнал, завершается.
Сигнал SIGINT (номер 2) обычно посылается процессу, если пользователь терминала дал команду прервать процесс (обычно эта команда – сочетание клавиш Ctrl-C) .
Сигнал SIGABRT (номер 6) посылается программе в результате вызова функции abort(3). В результате программа завершается с сохранением на диске образа памяти.
Сигнал SIGKILL (номер 9) завершает работу программы. Программа не может ни обработать, ни игнорировать этот сигнал.
Сигнал SIGSEGV (номер 11) посылается процессу, который пытается обратиться к не принадлежащей ему области памяти. Если обработчик сигнала не установлен, программа завершается с сохранением на диске образа памяти.
Сигнал SIGTERM (номер 15) вызывает «вежливое» завершение программы. Получив этот сигнал, программа может выполнить необходимые перед завершением операции (например, высвободить занятые ресурсы). Получение SIGTERM свидетельствует не об ошибке в программе, а о желании ОС или пользователя завершить ее.
Сигнал SIGCHLD (номер 17) посылается процессу в том случае, если его дочерний процесс завершился или был приостановлен. Родительский процесс также получит этот сигнал, если он установил режим отслеживания сигналов дочернего процесса и дочерний процесс получил какой-либо сигнал. По умолчанию сигнал SIGCHLD игнорируется.
Сигнал SIGCONT (номер 18) возобновляет выполнение процесса, остановленного сигналом SIGSTOP.
Сигнал SIGSTOP (номер 19) приостанавливает выполнение процесса. Как и SIGKILL, этот сигнал не возможно перехватить или игнорировать.
Сигнал SIGTSTP (номер 20) приостанавливает процесс по команде пользователя (обычно эта команда – сочетание клавиш Ctrl-Z).
Сигнал SIGIO/SIGPOLL (в Linux обе константы обозначают один сигнал – номер 29) сообщает процессу, что на одном из дескрипторов, открытых асинхронно, появились данные. По умолчанию этот сигнал, как ни странно, завершает работу программы.
В стандартной системе Unix определены два сигнала, SIGUSR1 (в Linux – номер 10) и SIGUSR2 (номер 12), предназначенные для передачи произвольной информации, но использование этих сигналов не приветствуется. Одной из причин негативного отношения программистов Unix к пользовательским сигналам является то, что сигналы, вообще говоря, представляют собой ограниченный ресурс, совместное использование которого может вызвать конфликты (например, если программист задействовал эти сигналы в своей программе и при этом использует стороннюю библиотеку, в которой эти сигналы также задействованы). Если вы не знали, то вам, возможно, будет интересно узнать, что обработка сигналов является частью стандарта языка Си и, как таковая, поддерживается даже на платформе Microsoft Windows. Однако, стандартный интерфейс сигналов Си, основанный на функции signal(), довольно неуклюж (недостатки интерфейса сигналов Си подробно описаны в книге [2]), так что мы воспользуемся более совершенным вариантом интерфейса, основанным на функции sigaction(2). Для демонстрации работы обработки сигналов мы напишем небольшую программу (файл sigdemo.c в исходниках).
Для функций, обрабатывающих потоки, существует и еще одно важное требование – реентерабильность. Поскольку обработчик сигнала может быть вызван в любой точке выполнения программы (а при не кототорых условиях во время обработки одного сигнала может быть вызван другой обработчик сигнала) в обработчиках додлжны использоваться функции, которые удовлетворяют требованию реентерабельности, то есть, могут быть вызваны в то время, когда они уже вызваны где-то в другой точке программы. Фактически, требование реентерабельности сводится к тому, чтобы функция не использовала никаких глобальных ресурсов, не позаботившись о синхронизации доступа к этим ресурсам. Некоторые функции ввода-вывода, в том числе, функция printf(), которую мы (и не только мы) используем в примерах обработчиков сигналов, реентерабельными не являются. Это значит, что выводу одной функции printf() может помешать вывод другой функции. В приложении приводится список реентерабельных функций, которые безопасно вызвать из обработчиков сигналов.
Единственным параметром нашего варианта функции-обработчика сигнала (в Unix-системах существует и другой вариант) является переменная типа int, в которой передается номер сигнала, вызвавшего обработчик. Нам этот номер не нужен, поскольку мы знаем, что только один сигнал, - SIGTERM, может вызвать нашу функцию, однако, в принципе, ничто не мешает нам использовать одну функцию для обработки нескольких разных сигналов, и тогда параметр функции- обработчика будет иметь для нас смысл. Функция-обработчик не возвращает никакого значения, что вполне логично, так как она вызывается не нашей программой, а неким системным компонентом. Особый интерес представляет завершение программы из обработчика сигнала. Назначение обработчика сигналу SIGTERM означает, что умалчиваемое действие сигнала, – завершение программы, не будет выполняться автоматически, и нам необходимо (если, конечно, мы хотим, чтобы этот сигнал завершал программу) позаботиться об этом явным образом. Если вы закомментируете вызов exit() в нашем примере, то увидите, что программа не будет завершать по получении сигнала SIGTERM. В принципе, вы можете придать сигналу SIGTERM совершенно иной смысл, например, оповещать программу о наступлении времени вашей любимой телепередачи (или о выходе нового номера журнала Linux Format), однако назначать стандартным сигналам нестандартные действия категорически не рекомендуется. Обработчик SIGTERM предназначен для того, чтобы, по требованию системы или пользователя, программа могла быстро и элегантно закончить текущую задачу и завершить свое выполнение. Именно этим обработчик и должен заниматься.
Перейдем теперь к тексту главной функции программы. Установка и удаление обработчиков сигналов осуществляются функцией sigaction(2). Первым параметром этой функции является номер сигнала, а в качестве второго и третьего параметров следует передать указатели на структуру sigaction. Эта структура содержит данные об операции, выполняемой над обработчиком сигнала. Второй параметр sigaction() служит для передачи новых значений для обработки сигнала, а третий – возвращает ранее установленные значения. В таблице 1 приводится краткое описание полей структуры sigaction.
Поле | Значение |
---|---|
sa_handler | Указатель на функцию обработчик сигнала или константа. |
sa_mask | Маска сигналов, блокируемых на время вызова обработчика. |
sa_flags | Дополнительные флаги. |
Таблица 1. Поля структуры sigaction.
Поле sa_handler должно содержать либо адрес функции-обработчика, либо специальную константу, указывающую, что нужно делать с сигналом. Константа SIG_IGN указывает, что сигнал следует игнорировать, а константа SIG_DFL – что нужно восстановить обработку сигнала, заданную системой по умолчанию. Поле sa_mask позволяет заблокировать некоторое множество сигналов на время выполнения обработчика данного сигнала. Делается это для того, чтобы обработка других сигналов не могла прервать обработку данного (это может быть необходимо, особенно, если один обработчик обрабатывает несколько разных сигналов). Параметр sa_flags позволяет задать ряд флагов для выполнения более тонкой настройки обработчика сигналов. Например, флаг SA_RESETHAND указывает, что после завершения обработки сигнала заданным обработчиком должен быть восстановлен обработчик, заданный по умолчанию, так что все последующие сигналы будут обрабатываться умалчиваемым обработчиком.
Рассмотрим теперь блокировку сигналов. Поскольку игнорирование сигнала устанавливается функцией sigaction(), можно было бы ожидать, что и блокировка устанавливается этой же функцией, но это не так. Так как зачастую программисту приходится блокировать несколько сигналов сразу, для блокировки существует специальная функция sigprocmask(2), которая оперирует наборами сигналов (signal sets). Разделение интерфейса между несколькими функциями вызвано еще и требованиями многопоточности. Параметры, устанавливаемые sigaction(), действительны для всей программы в целом, тогда как блокировку сигналов потоки осуществляют независимо друг от друга. Наборы сигналов хранятся в переменных специального типа - sigset_t, а операции над ними осуществляются с помощью специальных функций. Функция sigemptyset() инициализирует набор сигналов пустыми значениями, а функция sigfillset() устанавливает все возможные значения в наборе. Используемая нами функция sigaddset() добавляет значение сигнала в набор, а функция sigdelset() удаляет сигнал из набора. После того как набор сигналов сформирован, мы передаем его функции sigprocmask(), которая выполняет блокирование и разблокирование сигналов.
Первым параметром этой функции должна быть одна из констант, определяющих операцию над заданными сигналами. Константа SIG_BLOCK указывает, что сигналы из нового набора должны быть добавлены к списку уже заблокированных сигналов. Константа SIG_SETMASK указывает, что новый набор блокируемых сигналов должен заменить уже существующий (при этом заблокированные ранее сигналы будут разблокированы, если они не заблокированы в новом наборе), а константа SIG_UNBLOCK указывает на необходимость разблокировать сигналы, переданные в наборе. В нашей программе мы блокируем сигнал SIGHUP и вы можете видеть, что программа не обрабатывает этот сигнал. Послать нашей программе сигнал SIGHUP вы можете с помощью консольной команды где PID – идентификатор процесса.
Сигналы прерывают нормальный порядок выполнения программы и могут завершить работу программы, не способной завершиться иным образом. Но иногда бывает так, что программе просто нечего делать до тех пор, пока она не получит какой-либо сигнал. Иначе говоря, программу нужно заставить ждать появления сигнала, по возможности не нагружая процессор. Такая ситуация может возникнуть, например, в многопоточном программировании, когда нужно синхронизировать завершение нескольких потоков. Ожидание сигнала можно реализовать с помощью цикла, проверяющего значение флажка, который может сбросить обработчик сигнала. В некоторых случаях (таких как рассмотренный выше пример) можно реализовать ожидание и с помощью бесконечного цикла. Очевидно, однако, что эти методы не эффективны и не элегантны. В POSIX- системах существует специальная функция sigwait(3), которая «усыпляет» процесс до тех пор, пока процессу не будет передан один из заданного набора сигналов.
Модифицируем нашу программу так, чтобы вместо бесконечного цикла она входила в цикл ожидания сигнала SIGHUP (файл swdemo.c на компакт-диске):
Функцию sigwait() можно использовать и для исследования сигналов. На компакт-диске вы найдете программку siglog.c, которая распечатывает информацию о каждом поступившем сигнале (естественно, исследуются только те сигналы, которые могут быть заблокированы). Рассмотрим здесь фрагмент этой программы:
Таблица 2 демонстрирует поведение функции kill()в зависимости от значения PID:
PID > 1 | Сигнал посылается процессу с соответствующим PID. |
PID == 0 | Сигнал посылается всем процессам из той же группы что и процесс-источник. |
PID < 0 | Сигнал посылается всем процессам, чей идентификатор группы равен абсолютному значению PID. |
PID == 1 | Сигнал посылается всем процессам системы. |
Вызов эквивалентен вызову
Так же как и для других примитивов IPC, для сигналов действует система прав доступа, основанная на правах доступа владельцев процессов. Процесс-приемник получит сигнал только в том случае, если у процесса-источника есть соответствующие права. С помощью функции kill()можно проверить, существует ли в системе процесс с заданным PID, не посылая процессу никаких сигналов. Для этого предназначен псевдо-сигнал с номером 0. Если соответствующего процесса не существует, функция kill()вернет значение 1, соответствующее об ошибке. В любом случае, сигнал не будет отправлен. Читателей, полюбивших обработку сигналов, я могу обрадовать тем, что мы рассмотрели далеко не все функции, связанные с сигналами. При изучении документации вас ждет еще много полезного и приятного, мы же закончим на этом наше знакомство с сигналами.
В вашей системе есть страница man, на которой перечислены все имеющиеся сигналы, но доступ к этой странице происходит по-разному в зависимости от того, какая у вас операционная систем. В большинстве систем Linux страницу можно открыть с помощью команды man 7 signal. Если возникнут проблемы, то найдите точное месторасположение страницы man с помощью команды
Имена сигналов можно получить с помощью команды 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 и указать идентификатор процесса:
Когда процесс запускает несколько экземпляров, проще воспользоваться командой killall. В ней используются те же самые параметры, как и в команде kill, но она применяется ко всем экземплярам данного процесса. Испытайте эту команду прежде, чем ей воспользоваться на практике, поскольку в некоторых коммерческих версиях UNIX она может работать не так, как ожидается.
Всего в Linux 63 сигнала, обозначаемых своими номерами или символическими именами. Имена всех сигналов начинаются с SIG, и эту приставку часто опускают: так, сигнал, требующий прекратить выполнение процесса, называется SIGKILL, или KILL, или сигнал 9.
Получив сигнал, процесс может: игнорировать его; вызвать для обработки установленную по умолчанию функцию; вызвать собственный обработчик (перехватить сигнал). Некоторые сигналы (например, KILL) перехватить или игнорировать невозможно.
Пользователь может послать сигнал процессу с идентификатором PID командой
где <сигнал> — это номер или символическое имя.
Несколько часто встречающихся сигналов перечислены в таблице 3.1. Полный список можно получить по команде kill -l (list).
Сигналы Linux Таблица 3.1
№ Имя Назначение Реакция процесса-получателя 1 HUP Hangup — отбой Демоны перечитывают свои конфигурационные файлы 2 INT Interrupt Прекратить выполнение (перехватывается) 3 QUIT Сильнее, чем INT то же 4 ILL Illegal instruction. Программная ошибка Обработать ошибку. По умолчанию — прекратить выполнение 8 FPE Floating point exception Вычислительная ошибка (деление на ноль) Обработать ошибку. По умолчанию — прекратить выполнение 9 KILL Убить процесс Немедленно прекратить выполнение. Не перехватывается 11 SEGV Segmentation violation. Попытка доступа к чужой области памяти Обработать ошибку. По умолчанию — прекратить выполнение 13 PIPE Нет процесса, читающего из конвейера Обработать ошибку 15 TERM Termination. Завершить процесс Корректно завершить выполнение. Перехватывается 17 CHLD Завершился дочерний процесс Принять возвращенное им значение
Некоторые сигналы посылаются по нажатии комбинации клавиш. Так, Ctrl+C посылает сигнал INT, a Ctrl+ (обратный слэш) — сигнал QUIT. Получает эти сигналы тот процесс, который сейчас занимает консоль — например, ожидает вашего ввода.
Команда kill носит такое убийственное название потому, что чаще всего используется для принудительного завершения процессов, вышедших из-под контроля, забирающих много ресурсов или просто повисших. По умолчанию она посылает сигнал TERM. Он отличается от сигнала KILL тем, что приказывает процессу завершиться аккуратно, закрыв открытые им файлы, удалив временные и т.п. Сигнал же KILL действует на процесс как выстрел в голову.
Понятно, что для того, чтобы прервать выполнение процесса, нужно быть его хозяином или иметь привилегии суперпользователя.
Данный текст является ознакомительным фрагментом.
Продолжение на ЛитРес
Глава 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. Сигналы
27.3.10. Сигналы и сокеты
27.3.10. Сигналы и сокеты С сокетами связаны три сигнала:? SIGIO — сокет готов к вводу/выводу. Сигнал посылается процессу, который связан с сокетом;? SIGURG — сокет получил экспресс-данные (мы их использовать не будем, поэтому особо останавливаться на них нет смысла);? SIGPIPE — запись
7.2.6.2. Сигналы
7.2.6.2. Сигналы
3.3. Сигналы
Сигналы (классические):
Сигнал SIGHUP (номер 1) изначально был предназначен для того, чтобы информировать программу о потере связи с управляющим терминалом (терминалы часто подключались к системе с помощью модемов, так что название сигнала происходит от hung up – повесить трубку). Сигнал SIGHUP посылается приложению так же и в том случае, если процесс-лидер сессии завершил свою работу. Многие программы-демоны, у которых нет лидера сессии, так же обрабатывают этот сигнал. В ответ на получение SIGHUP демон обычно перезапускается (или просто повторно читает файл конфигурации). По умолчанию программа, получившая этот сигнал, завершается.
Сигнал SIGINT (номер 2) обычно посылается процессу, если пользователь терминала дал команду прервать процесс (обычно эта команда – сочетание клавиш Ctrl-C) .
Сигнал SIGABRT (номер 6) посылается программе в результате вызова функции abort(3). В результате программа завершается с сохранением на диске образа памяти.
Сигнал SIGKILL (номер 9) завершает работу программы. Программа не может ни обработать, ни игнорировать этот сигнал.
Сигнал SIGSEGV (номер 11) посылается процессу, который пытается обратиться к не принадлежащей ему области памяти. Если обработчик сигнала не установлен, программа завершается с сохранением на диске образа памяти.
Сигнал SIGTERM (номер 15) вызывает «вежливое» завершение программы. Получив этот сигнал, программа может выполнить необходимые перед завершением операции (например, высвободить занятые ресурсы). Получение SIGTERM свидетельствует не об ошибке в программе, а о желании ОС или пользователя завершить ее.
Сигнал SIGCHLD (номер 17) посылается процессу в том случае, если его дочерний процесс завершился или был приостановлен. Родительский процесс также получит этот сигнал, если он установил режим отслеживания сигналов дочернего процесса и дочерний процесс получил какой-либо сигнал. По умолчанию сигнал SIGCHLD игнорируется.
Сигнал SIGCONT (номер 18) возобновляет выполнение процесса, остановленного сигналом SIGSTOP.
Сигнал SIGSTOP (номер 19) приостанавливает выполнение процесса. Как и SIGKILL, этот сигнал не возможно перехватить или игнорировать.
Сигнал SIGTSTP (номер 20) приостанавливает процесс по команде пользователя (обычно эта команда – сочетание клавиш Ctrl-Z).
Сигнал SIGIO/SIGPOLL (в Linux обе константы обозначают один сигнал – номер 29) сообщает процессу, что на одном из дескрипторов, открытых асинхронно, появились данные. По умолчанию этот сигнал, как ни странно, завершает работу программы.
Итак, задача. Нам нужно организовать прием/передачу сигналов между двумя процессами. Но процессы у нас не простые. Один порождает другой. То есть один процесс будет родительским, а второй - дочерним.
Итак, начнем. ОС - Ubuntu Linux, компилятор - gcc.
Первый шаг - напишем функцию, которая будет порождать дочерний процесс.
Как известно, в Linux процессы порождаются функцией fork. Она клонирует текущий процесс. Чтобы сделать процесс, который выполняет другой код, нужно использовать функцию из семейства exec.
Разъясняю. fork - копирует процесс. Эта функция возвращает pid порожденного процесса. Если fork вернет значение меньше 0, то это значит что произошла ошибка, и продолжать нельзя. Нужно выйти.
Если fork вернет 0, это значит что процесс клонировался, и мы сейчас находимся в порожденном процессе. В данном случае мы вызываем функцию execl, которая назначает порожденному процессу новый исполняемый файл.
Код, который идет дальше - это код, который выполняет текущий процесс.
Дальше мы будем отправлять порожденному процессу сигналы. В качестве рабочего сигнала я выбрал SIGHUP.
Посылка сигнала выполняется с помощью функции kill(согласен, не сильно благозвучное название ).
Читайте также: