Читаем Linux API. Исчерпывающее руководство полностью

• Бит POLLWRBAND устанавливается в некоторых случаях, но не несет в себе никакой полезной информации (кроме того, его нельзя установить без использования битов POLLOUT и POLLWRNORM).

• Для получения определений констант POLLRDNORM, POLLRDBAND, POLLWRNORM и POLLWRBAND из заголовочного файла необходимо определить макрос проверки возможностей _XOPEN_SOURCE.

• Флаг POLLRDHUP применяется только в Linux и только с версией ядра 2.6.17. Чтобы получить его определение из файла , нужно определить макрос проверки возможностей _GNU_SOURCE.

• Бит POLLNVAL возвращается, если на момент вызова poll() заданный файловый дескриптор был закрыт.

Подводя итог всему вышесказанному, наиболее важными флагами вызова poll() являются POLLIN, POLLOUT, POLLPRI, POLLRDHUP, POLLHUP и POLLERR. Их назначение будет подробно описано в подразделе 59.2.3.

Аргумент timeout

Аргумент timeout влияет на блокировку вызова poll():

• если он равен –1, то блокировка происходит до тех пор, пока не станет готовым хотя бы один файловый дескриптор из массива fds (в соответствии с полем events) или не будет перехвачен сигнал;

• если он равен 0, то вызов проверяет готовность дескрипторов, не блокируясь;

• если он больше нуля, то блокировка происходит на протяжении timeout миллисекунд, пока не станет готовым один из файловых дескрипторов в массиве fds или не будет перехвачен сигнал.

Как и в случае с вызовом select(), точность аргумента timeout ограничена системными часами (см. раздел 10.6). А в стандарте SUSv3 сказано, что время ожидания округляется в большую сторону, если оно не делится без остатка.

Значение, возвращаемое вызовом poll()

В качестве результата вызов poll() возвращает одно из следующих значений:

• –1 в случае ошибки. Одной из возможных ошибок является EINTR, которая говорит о том, что вызов был прерван обработчиком сигнала (как отмечалось в разделе 21.5, в этой ситуации вызов poll() никогда не перезапускается автоматически);

• 0, если время ожидания истекло до того, как любой из файловых дескрипторов стал готовым;

• положительное значение, если один или несколько дескрипторов оказались готовыми. Это значение соответствует количеству структур pollfd в массиве fds, которые имеют ненулевое поле revents.

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

Пример программы

Простой пример использования вызова poll() демонстрируется в листинге 59.2. Программа создает несколько именованных каналов (каждый из которых задействует по два файловых дескриптора с соседними номерами), записывает байты во входящий конец одного из них, выбранного случайным образом, и затем выполняет вызов poll(), чтобы узнать, в каком канале можно прочитать данные.

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

$ ./poll_pipes 10 3

Writing to fd: 4 (read fd: 3)

Writing to fd: 14 (read fd: 13)

Writing to fd: 14 (read fd: 13)

poll() returned: 2

Readable: 3

Readable: 13

Как видите, вызов poll() нашел два канала с данными, доступными для чтения.

Листинг 59.2. Использование вызова poll() для мониторинга нескольких файловых дескрипторов

altio/poll_pipes.c

#include

#include

#include "tlpi_hdr.h"

int

main(int argc, char *argv[])

{

int numPipes, j, ready, randPipe, numWrites;

int (*pfds)[2]; /* Файловые дескрипторы для всех каналов */

struct pollfd *pollFd;

if (argc < 2 || strcmp(argv[1], "-help") == 0)

usageErr("%s num-pipes [num-writes]\n", argv[0]);

/* Выделяем место для наших массивов. Их размеры соответствуют

количеству каналов, заданному в командной строке */

numPipes = getInt(argv[1], GN_GT_0, "num-pipes");

pfds = calloc(numPipes, sizeof(int [2]));

if (pfds == NULL)

errExit("calloc");

pollFd = calloc(numPipes, sizeof(struct pollfd));

if (pollFd == NULL)

errExit("calloc");

/* Создаем столько каналов, сколько указано в командной строке */

for (j = 0; j < numPipes; j++)

if (pipe(pfds[j]) == -1)

errExit("pipe %d", j);

/* Выполняем заданное число операций записи в произвольные каналы */

numWrites = (argc > 2)? getInt(argv[2], GN_GT_0, "num-writes"): 1;

srandom((int) time(NULL));

for (j = 0; j < numWrites; j++) {

randPipe = random() % numPipes;

printf("Writing to fd: %3d (read fd: %3d)\n",

pfds[randPipe][1], pfds[randPipe][0]);

if (write(pfds[randPipe][1], "a", 1) == -1)

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

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

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных