[ Страница назад | Страница вперед | Содержание | Индекс | Библиотека | Юридическая информация | Поиск ]

Программирование: Разработка и отладка программ


Управление сигналами

Механизм управления сигналами в программах с несколькими нитями предназначен для предотвращения конфликтов. При этом сохраняется совместимость с обычными программами: сигналы в программах с несколькими нитями представляют собой расширения сигналов, применяемых в традиционных программах с одной нитью. Программы обработки сигналов, написанные для систем с одной нитью, будут правильно работать в AIX версии 4.

Управление сигналами в процессах с несколькими нитями осуществляется совместно процессом и нитями. Ниже перечислены элементы управления сигналами:

Кроме того, библиотека нитей предоставляет новую функцию для ожидания асинхронно поступающих сигналов и вводит новый набор приемов реализации такого ожидания.

Более подробно управление сигналами рассматривается в следующих разделах:

Обработчики сигналов и маски сигналов

Обработчики сигналов относятся к уровню процесса. Настоятельно рекомендуется считывать и устанавливать значения обработчиков сигналов только с помощью функции sigaction. Другие функции не будут поддерживаться в будущих версиях.

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

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

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

Генерация сигналов

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

Функция pthread_kill передает сигнал в нить. Поскольку ИД нитей идентифицируют их только в рамках процесса, эта функция может передавать сигналы в нити только данного процесса.

Функция kill (а следовательно, и команда kill) передает сигнал в процесс. Нить может передать сигнал Signal в процесс, запустивший ее, посредством следующего вызова:

kill(getpid(), Signal);

Функция raise не может применяться для передачи сигнала в процесс, запустивший вызывающую нить. Функция raise передает сигнал в вызывающую нить, как в следующем случае:

pthread_kill(pthread_self(), Signal);

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

Функция alarm запрашивает последующую передачу сигнала в процесс; при этом аварийные состояния обрабатываются на уровне процесса. Следовательно, последняя нить, вызвавшая функцию alarm, уничтожает соответствующие параметры для других нитей процесса. В программе с несколькими нитями сигнал SIGALRM не всегда передается в нить, вызвавшую функцию alarm. Может случиться, что вызывающая нить уже завершена и поэтому не может принять сигнал.

Обработка сигналов

Обработчики сигналов вызываются нитями, в которые поступили сигналы. Для определения ИД нити обработчик сигнала может вызвать функцию pthread_self. В библиотеке нитей реализован ряд ограничений для обработчиков сигналов:

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

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

sigset_t set;
int sig;

sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGQUIT);
sigaddset(&set, SIGTERM);
sigthreadmask(SIG_BLOCK, &set, NULL);

while (1) {
        sigwait(&set, &sig);
        switch (sig) {
                case SIGINT:
                        /* обработка прерываний */
                        break;
                case SIGQUIT:
                        /* обработка выхода */
                        break;
                case SIGTERM:
                        /* обработка завершения */
                        break;
                default:
                        /* сигнал, отличный от ожидаемого */
                        pthread_exit((void *)-1);
        }
}

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

Поскольку выделенная нить в действительности не является обработчиком сигналов, она может передать сигнал о выполнении условия (Использование условных переменных) в любую другую нить. Можно создать функцию sigwait_multiple, которая будет возобновлять выполнение всех нитей, ожидающих данного сигнала. Каждая нить, вызывающая функцию sigwait_multiple, может зарегистрировать свой набор сигналов. После этого нить будет ожидать изменения переменной условия. Одна нить вызывает функцию sigwait для всех зарегистрированных сигналов. При возврате из функции sigwait устанавливается соответствующее состояние и генерируются сигналы о выполнении условий. При повторном вызове функции sigwait_multiple ожидающий вызов функции sigwait будет отменен и потом возобновлен с новым набором сигналов.

Доставка сигналов

Сигнал поступает в нить, если он не должен игнорироваться. Доставка сигналов в процессах с несколькими нитями подчиняется следующим правилам:

Если ожидающий сигнал (на уровне нити или процесса) должен игнорироваться, то он игнорируется.

Связанная информация

Основные сведения о нитях.

Обзор взаимодействия между нитями и процессами.

Порождение и завершение процессов.

Планирование.

Список функций для взаимодействия между нитями и процессами.


[ Страница назад | Страница вперед | Содержание | Индекс | Библиотека | Юридическая информация | Поиск ]