Чтение онлайн

на главную - закладки

Жанры

Программирование для Linux. Профессиональный подход

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

Шрифт:

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

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;

void handler(int signal_number) {

 ++sigusr1_count;

}

int main {

 struct sigaction sa;

 memset(&sa, 0, sizeof(sa));

 sa.sa_handler = &handler;

 sigaction(SIGUSR1, &sa, NULL);

 /* далее идет основной текст. */

 /* ... */

 printf("SIGUSR1 was raised %d times\n", sigusr1_count);

 return 0;

}

3.4. Завершение процесса

Обычно процесс завершается одним из двух способов: либо выполняющаяся программа вызывает функцию

exit
, либо функция
main
заканчивается. У каждого процесса есть код завершения — число, возвращаемое родительскому процессу. Этот код передается в качестве аргумента функции
exit
или возвращается функцией
main
.

Возможно также аварийное завершение процесса, в ответ на получение сигнала. Таковыми могут быть, например, упоминавшиеся выше сигналы

SIGBUS
,
SIGSEGV
и
SIGFPE
. Есть сигналы, явно запрашивающие прекращение работы процесса. В частности, сигнал
SIGINT
посылается, когда пользователь нажимает <Ctrl+C>. Сигнал
SIGTERM
посылается процессу командной
kill
по умолчанию. Если программа вызывает функцию
abort
, она посылает сама себе сигнал
SIGABRT
. Самый "могучий" из всех сигналов —
SIGKILL
: он приводит к безусловному уничтожению процесса и не может быть ни блокирован, ни обработан.

Любой сигнал можно послать с помощью команды

kill
, указав дополнительный флаг. Например, чтобы уничтожить процесс, послав ему сигнал
SIGKILL
, воспользуйтесь следующей командой:

% kill -KILL идентификатор_процесса

Для отправки сигнала из программы предназначена функция

kill
. Ее первым аргументом является идентификатор процесса. Второй аргумент — номер сигнала (стандартному поведению команды
kill
соответствует сигнал
SIGTERM
). Например, если переменная
child_pid
содержит идентификатор дочернего процесса, то следующая функция, вызываемая из родительского процесса, вызывает завершение работы потомка:

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

Сердце Дракона. Том 20. Часть 1

Клеванский Кирилл Сергеевич
20. Сердце дракона
Фантастика:
фэнтези
боевая фантастика
городское фэнтези
5.00
рейтинг книги
Сердце Дракона. Том 20. Часть 1

Холодный ветер перемен

Иванов Дмитрий
7. Девяностые
Фантастика:
попаданцы
альтернативная история
6.80
рейтинг книги
Холодный ветер перемен

Последнее желание

Сапковский Анджей
1. Ведьмак
Фантастика:
фэнтези
9.43
рейтинг книги
Последнее желание

Отмороженный 7.0

Гарцевич Евгений Александрович
7. Отмороженный
Фантастика:
рпг
аниме
5.00
рейтинг книги
Отмороженный 7.0

Наследник

Кулаков Алексей Иванович
1. Рюрикова кровь
Фантастика:
научная фантастика
попаданцы
альтернативная история
8.69
рейтинг книги
Наследник

Магия чистых душ 2

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.56
рейтинг книги
Магия чистых душ 2

Наследие Маозари 5

Панежин Евгений
5. Наследие Маозари
Фантастика:
фэнтези
юмористическое фэнтези
5.00
рейтинг книги
Наследие Маозари 5

Локки 4 Потомок бога

Решетов Евгений Валерьевич
4. Локки
Фантастика:
аниме
фэнтези
5.00
рейтинг книги
Локки 4 Потомок бога

Граф

Ланцов Михаил Алексеевич
6. Помещик
Фантастика:
альтернативная история
5.00
рейтинг книги
Граф

Миф об идеальном мужчине

Устинова Татьяна Витальевна
Детективы:
прочие детективы
9.23
рейтинг книги
Миф об идеальном мужчине

Мастер Разума V

Кронос Александр
5. Мастер Разума
Фантастика:
городское фэнтези
попаданцы
5.00
рейтинг книги
Мастер Разума V

Здравствуй, 1984-й

Иванов Дмитрий
1. Девяностые
Фантастика:
альтернативная история
6.42
рейтинг книги
Здравствуй, 1984-й

Безумный Макс. Поручик Империи

Ланцов Михаил Алексеевич
1. Безумный Макс
Фантастика:
героическая фантастика
альтернативная история
7.64
рейтинг книги
Безумный Макс. Поручик Империи

Барон не играет по правилам

Ренгач Евгений
1. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон не играет по правилам