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

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

Жанры

UNIX: разработка сетевых приложений
Шрифт:

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

6.10. Функция poll

Функция

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

#include <poll.h>

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

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

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

pollfd
, задающая условия, проверяемые для данного дескриптора
fd
.

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

Свадьба по приказу, или Моя непокорная княжна

Чернованова Валерия Михайловна
Любовные романы:
любовно-фантастические романы
5.57
рейтинг книги
Свадьба по приказу, или Моя непокорная княжна

Сборник коротких эротических рассказов

Коллектив авторов
Любовные романы:
эро литература
love action
7.25
рейтинг книги
Сборник коротких эротических рассказов

Отец моего жениха

Салах Алайна
Любовные романы:
современные любовные романы
7.79
рейтинг книги
Отец моего жениха

Вадбольский

Никитин Юрий Александрович
1. Вадбольский
Фантастика:
попаданцы
5.00
рейтинг книги
Вадбольский

Бастард Императора. Том 7

Орлов Андрей Юрьевич
7. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 7

Повелитель механического легиона. Том VIII

Лисицин Евгений
8. Повелитель механического легиона
Фантастика:
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Повелитель механического легиона. Том VIII

В зоне особого внимания

Иванов Дмитрий
12. Девяностые
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
В зоне особого внимания

Таня Гроттер и магический контрабас

Емец Дмитрий Александрович
1. Таня Гроттер
Фантастика:
фэнтези
8.52
рейтинг книги
Таня Гроттер и магический контрабас

Бастард Императора. Том 2

Орлов Андрей Юрьевич
2. Бастард Императора
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бастард Императора. Том 2

Кодекс Крови. Книга ХI

Борзых М.
11. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХI

Третий

INDIGO
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий

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

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

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9

Потусторонний. Книга 1

Погуляй Юрий Александрович
1. Господин Артемьев
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Потусторонний. Книга 1