Мультиплексирование ввода при помощи poll(2)

Системный вызов poll(2) выполняет приблизительно те же задачи, что и select(3C), но использует несколько более удобный способ передачи информации о том, какие дескрипторы его интересуют. poll(2) имеет три параметра:

struct pollfd fds[] – массив описателей дескрипторов. Структура pollfd обсуждается далее в этом разделе

nfds_t nfds – количество описателей в массиве fds

int timeout – тайм-аут в миллисекундах. Если параметр timeout равен 0, poll работает в режиме опроса (возвращает управление немедленно). Если он равен -1, poll ждет готовности дескрипторов неограниченное время.

poll(2) возвращает количество дескрипторов, с которыми произошли какие-то события, запрошенные программой либо представляющие интерес для нее. Если poll(2) возвращает управление по тайм-ауту, код возврата будет равен 0. При ошибке poll(2) возвращает -1 и устанавливает errno.

Структура pollfd имеет следующие поля:

int fd – дескриптор файла. Если это поле имеет отрицательное значение, запись игнорируется.

short events – события, связанные с fd, которые нас интересуют.

short revents – return events, события, связанные с fd, которые реально произошли.

При вызове poll пользователь должен заполнить поля fd и events; поле revents заполняется системным вызовом.

Поля events и revents представляют собой битовые маски, биты которых соответствуют типам событий. Вместо битов рекомендуется использовать символьные константы, определенные в <poll.h>

Основные используемые типы событий – POLLIN (проверять готовность к чтению), и POLLOUT (проверять готовность к записи). В действительности, эти типы композитные и представляют собой сочетания разных типов событий. Так, для сокетов TCP можно указывать проверку поступления внеполосных данных, для устройств STREAMS – проверку поступления приоритетных данных и т.д. В revents устанавливаются биты, соответствующие реально происшедшему событию, т.е. если вы заказывали ожидание POLLIN, не обязательно в revents будут установлены все биты, входящие в маску POLLIN. Это необходимо иметь в виду при проверке revents (см. пример 2).

Кроме POLLIN и POLLOUT, в revents также могут появляться биты POLLERR, POLLHUP и POLLNVAL. В events эти биты игнорируются, а в revents могут быть установлены при следующих условиях:

POLLERR – на устройстве возникла ошибка

POLLHUP – сокет, труба или терминальное устройство закрыты на другом конце

POLLNVAL – значение fd не соответствует валидному файловому дескриптору (скорее всего, дескриптор был закрыт на нашем конце).


Использование poll(2) (фрагмент программы)

#include <poll.h>

struct pollfd fds[3];
int ifd1, ifd2, ofd, count;

fds[0].fd = ifd1;
fds[0].events = POLLNORM;
fds[1].fd = ifd2;
fds[1].events = POLLNORM;
fds[2].fd = ofd;
fds[2].events = POLLOUT;
count = poll(fds, 3, 10000);
if (count == -1) {
perror("poll failed");
exit(1);
}
if (count==0)
printf("No data for reading or writing\n");
if (fds[0].revents & POLLNORM)
printf("There is data for reading fd %d\n", fds[0].fd);
if (fds[1].revents & POLLNORM)
printf("There is data for reading fd %d\n", fds[1].fd);
if (fds[2].revents & POLLOUT)
printf("There is room to write on fd %d\n", fds[2].fd);


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: