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

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

Жанры

Разработка приложений в среде Linux. Второе издание

Троан Эрик В.

Шрифт:

sigprocmask(SIG_BLOCK, &hyp, NULL);

src = someString;

while(*src)

 *dest++ = *src++;

sigprocmask(SIG_UNBLOCK, &hup, NULL);

Сложность обеспечения безопасности обработчика сигналов от состояния состязаний должно заставить вас писать обработчики, насколько возможно, простыми.

12.2.5. Нахождение набора ожидающих сигналов

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

#include <signal.h>

int sigpending(sigset_t *set);

Эта функция записывает по адресу, указанному

set
, набор сигналов, которые в данный момент находятся в состоянии ожидания.

12.2.6. Ожидание сигналов

Когда программа построена преимущественно вокруг сигналов, часто необходимо, чтобы она ожидала появления какого-то сигнала, прежде чем продолжать работу. Системный вызов

pause
предоставляет простую возможность для этого.

#include <unistd.h>

int pause(void);

Функция

pause
не возвращает управления до тех пор, пока сигнал не будет доставлен процессу. Если зарегистрирован обработчик для этого сигнала, то он запускается до того, как
pause
вернет управление,
pause
всегда возвращает
– 1
и устанавливает
errno
равным
EINTR
.

Системный вызов

sigsuspend
предлагает альтернативный метод ожидания вызова сигнала.

#include <signal.h>

int sigsuspend(const sigset_t *mask);

Как

и
pause
,
sigsuspend
временно приостанавливает процесс до тех пор, пока не будет получен сигнал (и обработан связанным с ним обработчиком, если таковой предусмотрен), возвращая
– 1
и устанавливая
errno
в
EINTR
.

В отличие от

pause
,
sigsuspend
временно устанавливает маску сигналов процесса в значение, находящееся по адресу, указанному в
mask
, на период ожидания появления сигнала. Как только сигнал поступает, маска сигналов восстанавливается в то значение, которое она имела до вызова
sigsuspend
. Это позволяет процессу ожидать появления определенного сигнала за счет блокирования всех остальных сигналов [63] .

63

Применение

sigprocmask
и
pause
для получения требуемого поведения может вызвать состояние состязаний, если сигнал, появление которого ожидается, поступит между этими двумя системными вызовами.

12.3. Доступные сигналы

Linux предоставляет в распоряжение процессов сравнительно немного сигналов, и все они собраны в табл. 12.1.

Таблица 12.1. Сигналы

Сигнал Описание Действие по умолчанию
SIGABRT
Доставляется вызовом
abort
.
Прервать, сбросить дамп
SIGALRM
Истек срок действия
alarm
.
Прервать
SIGBUS
Ошибка, зависящая от оборудования. Прервать, сбросить дамп
SIGCHLD
Дочерний процесс прерван. Игнорировать
SIGCONT
Выполнение процесса продолжается после приостановки. Игнорировать
SIGFPE
Арифметическая ошибка. Прервать, сбросить дамп
SIGHUP
Закрыт процесс, управляющий терминалом. Прервать
SIGILL
Обнаружена недопустимая инструкция. Прервать
SIGINT
Пользователь послал символ прерывания (^C). Прервать
SIGIO
Принят асинхронный ввод-вывод. Прервать
SIGKILL
Не перехватываемое прерывание процесса. Прервать
SIGPIPE
Процесс пишет в канал при отсутствии читателя. Прервать
SIGPROF
Закончился сегмент профилирования. Прервать
SIGPWR
Обнаружен сбой питания. Прервать
SIGQUIT
Пользователь послал символ выхода (^\). Прервать, сбросить дамп
SIGSEGV
Нарушение памяти. Прервать, сбросить дамп
SIGSTOP
Приостановка процесса без его прерывания. Процесс приостановить
SIGSYS
Неверный системный вызов. Прервать, сбросить дамп
SIGTERM
Перехватываемый запрос на прерывание процесса. Прервать
SIGTRAP
Получена инструкция точки прерывания. Прервать, сбросить дамп
SIGTSTP
Пользователь послал символ приостановки (^Z). Процесс приостановить
SIGTTIN
Фоновый процесс читает с управляющего терминала. Процесс приостановить
SIGTTOU
Фоновый процесс пишет на управляющий терминал. Процесс приостановить
SIGURG
Условие срочного ввода-вывода. Игнорировать
SIGUSR1
Определяемый процессом сигнал. Прервать
SIGUSR2
Определяемый процессом сигнал. Прервать
SIGVTALRM
Таймер, установленный с помощью
setitimer
, устарел.
Прервать
SIGWINCH
Размер управляющего терминала изменился. Игнорировать
SIGXCPU
Достигнуто ограничение ресурсов центрального процессора. Прервать, сбросить дамп
SIGXFSZ
Достигнуто ограничение размера файла. Прервать, сбросить дамп

Предусмотрены четыре действия по умолчанию, которые ядро может предпринять при поступлении сигнала: игнорировать его, приостановить процесс (он остается жив и может быть перезапущен позднее), прервать процесс либо прервать процесс и сбросить дамп памяти ядра [64] . Ниже приведено более подробное описание каждого из перечисленных в табл. 12.1 сигналов.

SIGABRT
Функция
abort
посылает сигнал процессу, который ее вызвал, прерывая процесс со сбросом файла дампа ядра. Под Linux библиотека С вызывает
abort
, когда происходит сбой утверждения (assertion). Примечание. Утверждения описаны в книгах по С начального уровня, например, [15].
SIGALRM
Вызывается, когда предупреждение, установленное
alarm
, устаревает. Предупреждения (alarms) — это основа функции
sleep
, описанной в главе 18.
SIGBUS
Когда процесс нарушает ограничения, накладываемые оборудованием, но не связанные с защитой памяти, посылается этот сигнал. Обычно это случается на традиционных платформах Unix, когда выполняется попытка "невыровненного" доступа, но ядро Linux исправляет такие попытки и продолжает выполнять процесс. Выравнивание памяти обсуждается в главе 7.
SIGCHLD
Этот сигнал посылается процессу, когда один из его дочерних процессов устаревает или остановлен. Это позволяет процессу избежать появления "зомби" за счет вызова одной из функций
wait
из обработчика сигнала. Если родитель всегда ожидает завершения дочерних процессов, прежде чем продолжить работу, этот сигнал может быть проигнорирован. Это отличается от сигнала
SIGCHLD
, представленного в ранних версиях System V.
SIGCHLD
устарел и более не должен применяться.
SIGCONT
Этот сигнал перезапускает приостановленный процесс. Также он может быть вызван процессом, позволяющим выполнить действие после перезапуска. Большинство редакторов перехватывают этот сигнал и обновляют терминал после перезапуска. В главе 15 дана более подробная информация об останове и
перезапуске процесса.
SIGFPE
Этот сигнал посылается, когда процесс вызывает арифметическое исключение. Все исключения плавающей точки, такие как переполнение и потеря значимости, вызывают этот сигнал, как это происходит при делении на 0.
SIGHUP
Когда терминал отсоединяется, лидер сеанса, ассоциированного с терминалом, получает этот сигнал, если только на терминале не выставлен флаг
CLOCAL
. Если лидер сеанса завершается,
SIGHUP
отправляется лидеру каждой группы процессов в данном сеансе. Большинство процессов прерываются при получении
SIGHUP
, поскольку это значит, что пользователя уже нет в системе. Многие процессы-демоны интерпретируют
SIGHUP
как запрос на закрытие и повторное открытие журнальных файлов, а также на перечитывание конфигурационных файлов.
SIGILL
Процесс пытается запустить некорректную аппаратную команду.
SIGINT
Этот сигнал посылается всем процессам в группе процессов переднего плана, когда пользователь нажимает клавиатурную комбинацию прерывания (обычно ^C).
SIGIO
Произошло асинхронное событие ввода-вывода. Асинхронный ввод-вывод редко используется и в этой книге не описан. По вопросам асинхронного ввода-вывода обращайтесь к соответствующим источникам, например, [35].
SIGKILL
Этот сигнал генерируется только вызовом
kill
и разрешает пользователю безусловно прервать процесс.
SIGPIPE
Процесс выполнил запись в канал, который не имеет читателя.
SIGPROF
Завершилось действие таймера профилирования. Это сигнал обычно используется профилировщиками, которые проверяют другие характеристики процесса времени выполнения. Профилировщики обычно используются для оптимизации времени выполнения программ, помогая программистам находить узкие места. Простейшим профилировщиком является утилита
gprof
, входящая в состав всех дистрибутивов Linux.
SIGPWR
Система обнаружила надвигающуюся потерю питания. Обычно этот сигнал отправляется процессу init демоном, отслеживающим источники питания машины, позволяя корректно завершить работу до отключения питания.
SIGQUIT
Этот сигнал посылается всем процессам в группе процессов переднего плана, когда пользователь нажимает клавиатурную комбинацию завершения (обычно ^/).
SIGSEGV
Этот сигнал посылается, когда процесс пытается прочитать неотображаемую память, выполнить страницу памяти, которая не была отображена с привилегиями на выполнение, или же выполнить запись в память, к которой не имеет прав доступа на запись.
SIGSTOP
Этот сигнал генерируется только вызовом
kill
, и дает возможность пользователю безусловно остановить процесс. Более подробно о приостановке процессов можно почитать в главе 15.
SIGSYS
Когда программа пытается выполнить несуществующий системный вызов, ядро прерывает программу с помощью этого сигнала. Это никогда не должно происходить в программах, которые осуществляют системные вызовы посредством системой библиотеки С.
SIGTERM
Этот сигнал генерируется только вызовом
kill
и дает возможность пользователю элегантно прервать процесс. Процесс должен прекратиться насколько возможно быстро, немедленно после получения сигнала.
SIGTRAP
Когда программа проходит через точку прерывания, этот сигнал посылается процессу. Обычно он перехватывается процессом отладчика, который установил точку прерывания.
SIGTSTP
Этот сигнал посылается всем процессам в группе процессов переднего плана, когда пользователь нажимает клавиатурную комбинацию прерывания (обычно ^Z).
SIGTTIN
Этот сигнал посылается фоновому процессу, который пытается осуществить чтение из контролируемого им терминала. Об управлении заданиями подробнее читайте в главе 15.
SIGTTOU
Этот сигнал посылается фоновому процессу, который пытается осуществить запись на контролируемый им терминал. Об управлении заданиями подробнее читайте в главе 15.
SIGURG
Этот сигнал посылается, когда по сокету принимается экстренное сообщение. Экстренные данные — тема, касающаяся сетевых технологий, которая выходит за рамки освещаемых в настоящей книге. В [33] это рассматривается более подробно.
SIGUSR1
Для этого сигнала нет предопределенного назначения; процессы могут использовать его для собственных нужд.
SIGUSR2
Для этого сигнала нет предопределенного назначения; процессы могут использовать его для собственных нужд.
SIGVTALRM
Отправляется, когда истекает период действия таймера, установленного вызовом
settimer
. Информацию о применении таймеров можно найти в главе 18.
SIGWINCH
Когда окно терминала изменяет размер, например, когда пользователь растягивает окно
xterm
, все процессы в группе процессов переднего плана получают этот сигнал. В главе 16 представлена информация об определении текущего размера управляющего терминала.
SIGXCPU
Процесс превысил свой мягкий лимит использования ресурсов процессора. Этот сигнал посылается раз в секунду до тех пор, пока данный процесс не превысит жесткий лимит использования ресурсов процессора. Как только это произойдет, процесс прерывается сигналом
SIGKILL
. Информацию о лимитах ресурса процессора можно найти в главе 10.
SIGXFSZ
Когда программа превышает лимит максимального размера файла, ей посылается этот сигнал, что обычно уничтожает процесс. Если сигнал перехвачен, то системный вызов, который послужил причиной превышения лимита на размер файла, возвращает ошибку
EFBIG
. Информацию о лимитах ресурса процессора можно найти в главе 10.

64

Более подробно о дампах памяти рассказывается в главе 10.

12.3.1. Описание сигналов

Иногда приложения нуждаются в описании сигнала для отображения пользователю или помещения в журнал. Существуют три способа сделать это (см. главу 9). К сожалению, ни один из них не стандартизован.

Самый старый метод предусматривает применение

sys_siglist
— массива строк, описывающих каждый сигнал, проиндексированного номерами самих сигналов. Он включает описания всех сигналов за исключением сигналов реального времени. Применение
sys_siglist
более переносимо, чем прочие методы, описанные ниже. В системах BSD предусмотрена функция
psignal
, которая является сокращенным способом отображения сообщений. Вот как выглядит версия
psignal
.

#include <signal.h>

#include <stdio.h>

void psignal(int signum, const char *msg) {

 printf("%s: %s\n", msg, sys_siglist[signum]);

}

Следует отметить, что эта функция использует тот же список сигналов, что и

sys_siglist
, поэтому сигналы реального времени также исключаются.

Библиотека GNU С, используемая Linux, предлагает еще один метод —

strsignal
. Эта функция не входит ни в какой стандарт, поэтому для доступа к файлу прототипа нужно определить
_GNU_SOURCE
.

#define _GNU_SOURCE

#include <signal.h>

char *strsignal(int signum);

Подобно

sys_siglist
,
strsignal
также представляет описание сигнала по номеру
signum
. Он использует
sys_siglist
для большинства сигналов и конструирует описания для сигналов реального времени. Например,
SIGRTMIN + 5
будет описан как "Real-time signal 5". Пример использования
strsignal
можно найти в строках 639–648 и 717 файла
ladsh4.с
, приведенного в приложении Б.

12.4. Написание обработчиков сигналов

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

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

Мимик нового Мира 10

Северный Лис
9. Мимик!
Фантастика:
юмористическое фэнтези
альтернативная история
постапокалипсис
рпг
5.00
рейтинг книги
Мимик нового Мира 10

Польская партия

Ланцов Михаил Алексеевич
3. Фрунзе
Фантастика:
попаданцы
альтернативная история
5.25
рейтинг книги
Польская партия

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

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

Темный Лекарь 3

Токсик Саша
3. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Темный Лекарь 3

Назад в СССР: 1986 Книга 5

Гаусс Максим
5. Спасти ЧАЭС
Фантастика:
попаданцы
альтернативная история
5.75
рейтинг книги
Назад в СССР: 1986 Книга 5

Наследница Драконов

Суббота Светлана
2. Наследница Драконов
Любовные романы:
современные любовные романы
любовно-фантастические романы
6.81
рейтинг книги
Наследница Драконов

Кодекс Охотника. Книга XIII

Винокуров Юрий
13. Кодекс Охотника
Фантастика:
боевая фантастика
попаданцы
аниме
7.50
рейтинг книги
Кодекс Охотника. Книга XIII

Не кровный Брат

Безрукова Елена
Любовные романы:
эро литература
6.83
рейтинг книги
Не кровный Брат

Ты нас предал

Безрукова Елена
1. Измены. Кантемировы
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Ты нас предал

Возвышение Меркурия. Книга 5

Кронос Александр
5. Меркурий
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 5

Последний Паладин. Том 7

Саваровский Роман
7. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 7

Клан

Русич Антон
2. Долгий путь домой
Фантастика:
боевая фантастика
космическая фантастика
5.60
рейтинг книги
Клан

Калибр Личности 1

Голд Джон
1. Калибр Личности
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Калибр Личности 1

Вторая жизнь майора. Цикл

Сухинин Владимир Александрович
Вторая жизнь майора
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Вторая жизнь майора. Цикл