Читаем UNIX: разработка сетевых приложений полностью

Эти структуры отличаются вторыми элементами: элемент 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, но мы не меняли его тип, чтобы не разрушать существующего кода. Однако в новой функции это можно было бы сделать.

<p>6.10. Функция poll</p>

Функция poll появилась впервые в SVR3, и изначально ее применение ограничивалось потоковыми устройствами (STREAMS devices) (см. главу 31). В SVR4 это ограничение было снято, что позволило функции poll работать с любыми дескрипторами. Функция poll предоставляет функциональность, аналогичную функции select, но позволяет получать дополнительную информацию при работе с потоковыми устройствами.

#include

int poll(struct pollfd *fdarray, unsigned long nfds, int timeout);

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

Первый аргумент — это указатель на первый элемент массива структур. Каждый элемент массива — это структура pollfd, задающая условия, проверяемые для данного дескриптора fd.

struct pollfd {

 int fd;        /* дескриптор, который нужно проверить */

 short events;  /* события на дескрипторе, которые нас интересуют */

Перейти на страницу:

Все книги серии Мастер-класс

Секреты резьбы по дереву
Секреты резьбы по дереву

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

Галина Алексеевна Серикова

Сделай сам / Хобби и ремесла / Руководства / Дом и досуг / Словари и Энциклопедии

Похожие книги