Вход/Регистрация
Программирование для Linux. Профессиональный подход
вернуться

Самьюэл Алекс

Шрифт:

3.3. Сигналы

Сигналы — это механизм связи между процессами в Linux. Данная тема очень обширна, поэтому здесь мы рассмотрим лишь наиболее важные сигналы и методики управления процессами.

Сигнал представляет собой специальное сообщение, посылаемое процессу. Сигналы являются асинхронными: когда процесс принимает сигнал, он немедленно обрабатывает его, прерывая выполнение текущей функции и даже текущей строки программы. Есть несколько десятков различных сигналов, каждый из которых имеет свое функциональное назначение. Все они распознаются по номерам, но в программах для ссылки на сигналы пользуются символическими константами. В Linux эти константы определены в файле /usr/include/bits/signum.h (его не нужно включать в программы, для этого есть файл <signal.h>).

В ответ на полученный сигнал процесс выполняет ряд действий в зависимости от типа сигнала. У каждого сигнала есть стандартный обработчик, определяющий, что произойдет с процессом, если он попытается проигнорировать сигнал. Для большинства сигналов можно также задавать явную функцию обработки. В этом случае при поступлении сигнала выполнение программы приостанавливается, выполняется обработчик, а потом программа возобновляет свою работу.

Операционная система Linux посылает процессам сигналы в случае возникновения определенных ситуаций. Например, сигналы

SIGBUS
(ошибка на шине),
SIGSEGV
(нарушение сегментации) и
SIGFPE
(ошибка операции с плавающей запятой) могут быть посланы процессу, пытающемуся выполнить неправильную операцию. По умолчанию эти сигналы приводят к завершению процесса и созданию дампа оперативной памяти.

Процесс может сам послать сигнал другому процессу. Чаще всего возникает необходимость завершить требуемый процесс с помощью сигнала

SIGTERM
или
SIGKILL
. [12] С помощью сигналов можно также передавать команды выполняющимся программам. Для этого существуют "пользовательские" сигналы
SIGUSR1
и
SIGUSR2
. Иногда в аналогичных целях применяется сигнал
SIGHUP
, с помощью которого можно заставить программу повторно прочитать свои файлы конфигурации.

12

В чём между ними разница! Сигнал

SIGTERM
является запросам на завершение; процесс может его проигнорировать и продолжить свое выполнение.. Сигнал
SIGKILL
вызывает немедленное безусловное уничтожение процесса и не может быть обработан.

Функция

sigaction
определяет правила обработки указанного сигнала. Первый ее аргумент — это номер сигнала. Следующие два аргумента представляют собой указатели на структуру
sigaction
; первый из них регистрирует новый обработчик сигнала, а второй содержит описание предыдущего обработчика. Наиболее важным полем структуры
sigaction
является
sa_handler
. Оно может содержать одно из трех значений:

■ 

SIG_DFL
— выбор стандартного обработчика сигнала;

■ 

SIG_IGN
— игнорирование сигнала,

■ указатель на функцию обработки сигнала; эта функция должна принимать один параметр (номер сигнала) и возвращать значение типа

void
.

Поскольку сигнал может прийти в любой момент, он способен застать программу "врасплох" за выполнением критической операции, не подразумевающей прерывание. Такой операцией, к примеру, является обработка предыдущего сигнала. Отсюда правило: следует избегать операций ввода-вывода и вызовов большинства библиотечных и системных функций в обработчиках сигналов.

Обработчик должен выполнять минимум действий в ответ на получение сигнала и как можно быстрее возвращать управление в программу (или просто завершать ее работу). В большинстве случаев обработчик просто фиксирует факт поступления сигнала, а основная программа периодически проверяет, был ли сигнал, и реагирует должным образом.

Тем не менее возможность прерывания обработчика никогда нельзя исключать. Это очень сложная ситуация для диагностирования и отладки (и наглядный пример состояния гонки, о котором пойдет речь в разделе 4.4. "Синхронизация потоков и критические секции"). Необходимо внимательно следить за тем, что именно делается в обработчике.

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

sig_atomic_t
. Linux гарантирует, что операция присваивания значения такой переменной займет ровно один такт и не будет прервана. На самом деле тип
sig_atomic_t
в Linux эквивалентен типу
int
; более того, операции присваивания целочисленных переменных (32- и 16-разрядных) и указателей всегда атомарны. Использовать тип
sig_atomic_t
необходимо для того, чтобы программу можно было перенести в любую стандартную UNIX-систему.

В листинге 3.5 представлен шаблон программы, в которой функция-обработчик подсчитывает, сколько раз программа получает сигнал

SIGUSR1
.

Листинг 3.5. (sigusr1.c) Корректное применение обработчика сигнала

#include <signal.h>

#include <stdio.h>

#include <string.h>

#include <sys/types.h>

#include <unistd.h>

sig_atomic_t sigusr1_count = 0;

  • Читать дальше
  • 1
  • ...
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: