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

• Открывает для ввода каждый файл, указанный в командной строке и добавляет соответствующие файловые дескрипторы в список интереса для экземпляра epoll . В качестве значения, определяющего набор отслеживаемых событий, используется EPOLLIN.

• Входит в цикл , который вызывает epoll_wait() для мониторинга списка интереса для экземпляра epoll и обрабатывает события, возвращаемые каждым вызовом. Следует сделать несколько замечаний относительно этого цикла.

• После вызова epoll_wait() программа проверяет наличие ошибки EINTR , которая может произойти, если выполнение было остановлено по сигналу прямо во время работы epoll_wait() и возобновлено с помощью сигнала SIGCONT (см. раздел 21.5). В этом случае программа перезапускает вызов epoll_wait().

• Если вызов epoll_wait() завершается успешно, программа входит в еще один цикл, чтобы проверить готовность каждого элемента в списке evlist . Для этого в поле events каждого элемента ищется не только значение EPOLLIN, но также EPOLLHUP и EPOLLERR . Оба последних события возникают в ситуации, когда закрывается другой конец очереди FIFO или разрывается соединение с терминалом. Если возвращается EPOLLIN, то программа считывает ввод из соответствующего файлового дескриптора и направляет его в стандартный вывод. В противном случае дескриптор закрывается , а счетчик открытых файлов (numOpenFds) уменьшается на 1.

• Цикл завершается при закрытии всех дескрипторов открытых файлов (то есть когда переменная numOpenFds равна 0).

Пример использования программы из листинга 59.5 приводится в следующих сессиях командной строки. Мы применяем два терминала. В первом наша программа отслеживает ввод в двух очередях FIFO (каждая из них открывается для чтения и будет закрыта только тогда, когда другой ее конец будет открыт для записи другим процессом; см. раздел 44.7). Во втором терминале запускаем несколько экземпляров команды cat(1), которые записывают данные в ранее упомянутые очереди FIFO.

Terminal window 1 Terminal window 2

$ mkfifo p q

$ ./epoll_input p q

$ cat > p

Opened "p" on fd 4

Нажимаем Ctrl+Z, чтобы приостановить cat

[1]+ Stopped cat >p

$ cat > q

Opened "q" on fd 5

About to epoll_wait()

Нажимаем Ctrl+Z, чтобы приостановить программу epoll_input

[1]+ Stopped./epoll_input p q

Выше мы приостановили нашу программу мониторинга для получения возможности сгенерировать ввод для очередей FIFO и закрыть записывающий конец одной из них:

qqq

Нажимаем Ctrl+D, чтобы завершить команду "cat > q"

$ fg %1

cat >p

ppp

Теперь мы возобновляем нашу программу мониторинга, переводя ее в активный режим. После этого вызов epoll_wait() возвращает два события:

$ fg

./epoll_input p q

About to epoll_wait()

Ready: 2

fd=4; events: EPOLLIN

read 4 bytes: ppp

fd=5; events: EPOLLIN EPOLLHUP

read 4 bytes: qqq

closing fd 5

About to epoll_wait()

Две пустые строки в вышеприведенном выводе являются символами новой строки, которые были прочитаны экземплярами cat, записаны в очереди FIFO, а затем прочитаны и выведены нашей программой.

Далее мы нажимаем Ctrl+D во втором терминале, чтобы завершить оставшийся экземпляр cat; это опять приводит к завершению вызова epoll_wait(), который теперь возвращает всего одно событие:

Нажимаем Ctrl+D, чтобы завершить команду “cat > p”

Ready: 1

fd=4; events: EPOLLHUP

closing fd 4

All file descriptors closed; bye

Листинг 59.5. Использование программного интерфейса epoll

altio/epoll_input.c

#include

#include

#include "tlpi_hdr.h"

#define MAX_BUF 1000 /* Максимальный объем данных, получаемых за одно чтение */

#define MAX_EVENTS 5 /* Максимальное количество событий,

возвращаемых одним вызовом epoll_wait() */

int

main(int argc, char *argv[])

{

int epfd, ready, fd, s, j, numOpenFds;

struct epoll_event ev;

struct epoll_event evlist[MAX_EVENTS];

char buf[MAX_BUF];

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

usageErr("%s file…\n", argv[0]);

epfd = epoll_create(argc — 1);

if (epfd == -1)

errExit("epoll_create");

/* Открываем каждый файл в командной строке и добавляем его

в «список интереса» экземпляра epoll */

for (j = 1; j < argc; j++) {

fd = open(argv[j], O_RDONLY);

if (fd == -1)

errExit("open");

printf("Opened \"%s\" on fd %d\n", argv[j], fd);

ev.events = EPOLLIN; /* Нас интересуют только события ввода */

ev.data.fd = fd;

 if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) == -1)

errExit("epoll_ctl");

}

numOpenFds = argc — 1;

while (numOpenFds > 0) {

/* Извлекаем элемент из списка готовности (максимум MAX_EVENTS) */

printf("About to epoll_wait()\n");

 ready = epoll_wait(epfd, evlist, MAX_EVENTS, — 1);

if (ready == -1) {

 if (errno == EINTR)

continue;

/* Перезапускаем, если операция была прервана сигналом */

else

errExit("epoll_wait");

}

printf("Ready: %d\n", ready);

/* Обрабатываем полученный список событий */

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

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

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

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

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

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

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

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

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

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