6.9. Функция pselect

6.9. Функция pselect

Функция pselect была введена в POSIX и в настоящий момент поддерживается множеством версий Unix.

#include <sys/select.h>

#include <signal.h>

#include <time.h>

int pselect(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,

 const struct timespec *timeout, const sigset_t *sigmask);

Возвращает: количество готовых дескрипторов, 0 в случае тайм-аута, -1 в случае ошибки

Функция pselect имеет два отличия от обычной функции select:

1. Функция pselect использует структуру timespec, нововведение стандарта реального времени POSIX, вместо структуры timeval.

struct timespec {

 time_t tv_sec; /* секунды */

 long tv_nsec;  /* наносекунды */

};

Эти структуры отличаются вторыми элементами: элемент tv_nsec новой структуры задает наносекунды, в то время как элемент tv_usec прежней структуры задает микросекунды.

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

В отношении второго пункта рассмотрим следующий пример (описанный на с. 308–309 [110]). Обработчик сигнала нашей программы для сигнала SIGINT просто устанавливает глобальную переменную intr_flag и возвращает управление. Если наш процесс блокирован в вызове функции select, возвращение из обработчика сигнала заставляет функцию завершить работу, присвоив errno значение EINTR. Код вызова select выглядит следующим образом:

if (intr_flag)

 handle_intr(); /* обработка этого сигнала */

if ((nready = select(...)) < 0) {

 if (errno == EINTR) {

  if (intr_flag)

   handle_intr();

 }

 ...

}

Проблема заключается в том, что если сигнал придет в промежутке между проверкой переменной intr_flag и вызовом функции select, он будет потерян в том случае, если функция select заблокирует процесс навсегда. С помощью функции pselect мы можем переписать этот пример так, чтобы он работал более надежно:

sigset_t newmask, oldmask, zeromask;

sigemptyset(&zeromask);

sigemptyset(&newmask);

sigaddset(&newmask, SIGINT);

sigprocmask(SIG_BLOCK, &newmask, &oldmask); /* блокирование сигнала SIGINT */

if (intr_flag)

 handle_intr(); /* обработка этого сигнала */

if ((nready = pselect(..., &zeromask)) < 0) {

 if (errno == EINTR) {

  if (intr_flag)

  handle_intr();

 }

 ...

}

Перед проверкой переменной intr_flag мы блокируем сигнал SIGINT. Когда вызывается функция pselect, она заменяет маску сигналов процесса пустым набором (zeromask), а затем проверяет дескрипторы, возможно, переходя в состояние ожидания. Но когда функция pselect возвращает управление, маске сигналов процесса присваивается то значение, которое предшествовало вызову функции pselect (то есть сигнал SIGINT блокируется).

Мы поговорим о функции pselect более подробно и приведем ее пример в разделе 20.5. Функцию pselect мы используем в листинге 20.3, а в листинге 20.4 показываем простую, хотя и не вполне корректную реализацию этой функции.

ПРИМЕЧАНИЕ

Есть одно незначительное различие между функциями select и pselect. Первый элемент структуры timeval является целым числом типа long со знаком, в то время как первый элемент структуры timspec имеет тип time_t. Число типа long со знаком в первой функции также должно было относиться к типу time_t, но мы не меняли его тип, чтобы не разрушать существующего кода. Однако в новой функции это можно было бы сделать.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Функция SUM

Из книги Обработка баз данных на Visual Basic®.NET автора Мак-Манус Джеффри П

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


Функция uni()

Из книги Fiction Book Designer Краткое руководство автора Автор неизвестен

Функция uni() Поиск/замена символа по его юникодному номеру также может быть сделана при помощи функции uni().Пример функции uni(): Boouni(107,32)Designer найдет слово Book


Функция uni()

Из книги Fiction Book Designer 3.2. Краткое руководство автора Izekbis

Функция uni() Поиск/замена символа по его юникодному номеру также может быть сделана при помощи функции uni().Пример функции uni(): Boouni(107,32)Designer найдет слово Book


Функция signal_rt

Из книги UNIX: взаимодействие процессов автора Стивенс Уильям Ричард

Функция signal_rt В книге [24, с. 120] мы привели пример собственной функции signal, вызывавшей функцию sigaction стандарта Posix для установки обработчика сигнала, обеспечивающего надежную семантику Posix. Изменим эту функцию, чтобы обеспечить поддержку реального времени. Новую функцию мы


Функция mq_notify

Из книги Технология XSLT автора Валиков Алексей Николаевич

Функция mq_notify Функция mq_notify, текст которой приведен в листинге 5.24, позволяет регистрировать процесс на уведомление для текущей очереди и снимать его с регистрации. Информация о зарегистрированных процессах (их идентификаторы) хранится в поле mqh_pid структуры mq_hdr. Только


6.4. Функция msgrcv

Из книги PGP: Кодирование и шифрование информации с открытым ключом. автора Левин Максим

6.4. Функция msgrcv Сообщение может быть считано из очереди с помощью функции msgrcv.#include <sys/msg.h>ssize_t msgrcv(int msqid, void *ptr, size_t length, long type, int flag);/* Возвращает количество данных в сообщении, –1 – в случае ошибки */Аргумент ptr указывает, куда следует помещать принимаемые данные. Как и для


6.5. Функция msgctl

Из книги Fiction Book Designer 3.2. Руководство по созданию книг автора

6.5. Функция msgctl Функция msgctl позволяет управлять очередями сообщений:#include <sys/msg.h>int msgctl(int msqid, int cmd, struct msqid_ds *buff);/* Возвращает 0 в случае успешного завершения, –1 в случае ошибки */Команд (аргумент cmd) может быть три:? IPC_RMID — удаление очереди с идентификатором msqidиз системы.


Функция not

Из книги Введение в криптографию автора Циммерманн Филипп


Функция sum

Из книги UNIX: разработка сетевых приложений автора Стивенс Уильям Ричард


Хэш-функция.

Из книги автора

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


Функция uni()

Из книги автора

Функция uni() Поиск/замена символа по его юникодному номеру также может быть сделана при помощи функции uni().Пример функции uni(): Boouni(107,32)Designer найдет слово Book


Хэш-функция

Из книги автора

Хэш-функция Однако описанная выше схема имеет ряд существенных недостатков. Она крайне медлительна и производит слишком большой объём данных — по меньшей мере вдвое больше объёма исходной информации. Улучшением такой схемы становится введение в процесс преобразования


Блокирование и разблокирование сигнала с помощью функции pselect

Из книги автора

Блокирование и разблокирование сигнала с помощью функции pselect Одним из корректных решений будет использование функции pselect (см. раздел 6.9), как показано в листинге 20.3.Листинг 20.3. Блокирование и разблокирование сигналов с помощью функции pselect//bcast/dgclibcast4.с 1 #include "unp.h" 2 static