7.2.6.2. Сигналы

7.2.6.2. Сигналы

Самый простой и грубый способ сообщения между двумя процессами на одной машине заключается в том, что один из них отправляет другому какой-либо сигнал (signal). Сигналы в операционной системе Unix представляют собой форму программного прерывания. Каждый сигнал характеризуется стандартным влиянием на получающий его процесс (обычно процесс уничтожается). Процессом может быть объявлен обработчик сигналов (signal handler), который подменяет их стандартные действия. Обработчик представляет собой функцию, которая выполняется асинхронно при получении сигнала.

Первоначально сигналы были встроены в Unix не как средство IPC, а как способ, позволяющий операционной системе сообщать программам об определенных ошибках и критических событиях. Например, сигнал SIGHUP отправляется каждой программе, запущенной из определенного терминального сеанса, когда этот сеанс завершается. Сигнал SIGINT отправляется любому процессу, подключенному в текущий момент времени к клавиатуре, когда пользователь вводит определенный символ прерывания (часто control-C). Тем не менее, сигналы могут оказаться полезными в некоторых IPC-ситуациях (и в набор сигналов стандарта POSIX включено два сигнала, предназначенных для таких целей, SIGUSR1 и SIGUSR2). Часто они используются как канал управления для демонов (daemons) (программы, которые работают постоянно и невидимо, т.е. в фоновом режиме). Это способ для оператора или другой программы сообщить демону о том, что он должен повторно инициализироваться, выйти из спящего режима для выполнения работы или записать в определенное место сведения о внутреннем состоянии или отладочную информацию.

Я настаивал на том, чтобы сигналы SIGUSR1 и SIGUSR2 были созданы для BSD. Люди хватались за системные сигналы, чтобы заставить их делать то, что им нужно для IPC, так что (например) некоторые программы, которые аварийно завершались в результате ошибки сегментации, не создавали дамп памяти, потому что сигнал SIGSEGV был модифицирован.

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

Кен Арнольд.

Методика, которая часто применяется с сигнальным IPC, также называется pid-файлом. Программы, которым требуется получать сигналы, записывают небольшие файлы, содержащие идентификатор процесса или PID (process ID), в определенный каталог (часто /var/run или домашний каталог запускающего программу пользователя). Другие программы могут считывать данный файл для определения PID. PID-файл также может служить в качестве неявного файла блокировки (lock file) в случаях, когда необходимо запустить одновременно не более одного экземпляра демона.

Фактически существует две различные разновидности сигналов. В ранних реализациях (особенно в V7, System III и в ранней System V) обработчик для определенного сигнала каждый раз после срабатывания переустанавливается в стандартное состояние. Следовательно, в результате двух одинаковых сигналов, отправленных быстро друг за другом, процесс обычно уничтожается независимо от того, какой обработчик был установлен.

Версии 4.x BSD Unix перешли к использованию "надежных" сигналов, которые не переустанавливаются, если пользователь не требует этого явно. Также в данных версиях были представлены примитивы для блокировки или временной приостановки обработки определенного набора сигналов. В современных Unix-системах поддерживается оба стиля. Для нового кода следует использовать непереустанавливаемые точки входа в BSD-стиле, однако в случае если код когда-либо будет переноситься в реализацию, которая не поддерживает их, необходимо использовать методику "безопасного программирования".

Получение N сигналов не обязательно N раз вызывает обработчик сигналов. В старой модели сигналов System V два или более сигнала, поданные очень близко (т.е. в одном кванте времени целевого процесса), могут привести к различным проявлениям конкуренции[73] или аномалиям. В зависимости от варианта семантики сигналов, который поддерживается в системе, второй и последующие экземпляры могут игнорироваться, вызывать неожиданное завершение процесса или задерживаться, пока обрабатываются предыдущие экземпляры (в современных Unix-системах последней вариант наиболее вероятен).

Современный API-интерфейс сигналов переносится на все последние версии Unix, но не на Windows или классическую (предшествующую OS X) MacOS.

Данный текст является ознакомительным фрагментом.