Разработка приложений в среде Linux. Второе издание
Шрифт:
Сложность обеспечения безопасности обработчика сигналов от состояния состязаний должно заставить вас писать обработчики, насколько возможно, простыми.
12.2.5. Нахождение набора ожидающих сигналов
Очень легко найти сигналы, находящиеся в состоянии ожидания (сигналы, которые должны быть доставлены, но в данный момент заблокированы).
Эта функция записывает по адресу, указанному
12.2.6. Ожидание сигналов
Когда программа построена преимущественно вокруг сигналов, часто необходимо, чтобы она ожидала появления какого-то сигнала, прежде чем продолжать работу. Системный вызов
Функция
Системный вызов
Как
В отличие от
63
Применение
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). К сожалению, ни один из них не стандартизован.
Самый старый метод предусматривает применение
Следует отметить, что эта функция использует тот же список сигналов, что и
Библиотека GNU С, используемая Linux, предлагает еще один метод —
Подобно
12.4. Написание обработчиков сигналов
Хотя обработчик сигнала выглядит подобно обычной функции С, он не вызывается так, как она. Вместо того чтобы быть частью нормальной последовательности вызовов программы, обработчик вызывается ядром. Ключевое различие между этими двумя вещами заключается в том, что обработчик может быть вызван почти в любое время, даже во время выполнения отдельного оператора С! Есть только несколько ограничений того, когда система может вызвать обработчик сигнала, на который вы полагаетесь.