Читаем 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++) {

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

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

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных
1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

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

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

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

В этом полном руководстве по C# 4.0 - языку программирования, разработанному специально для среды .NET, - детально рассмотрены все основные средства языка: типы данных, операторы, управляющие операторы, классы, интерфейсы, методы, делегаты, индексаторы, события, указатели, обобщения, коллекции, основные библиотеки классов, средства многопоточного программирования и директивы препроцессора. Подробно описаны новые возможности C#, в том числе PLINQ, библиотека TPL, динамический тип данных, а также именованные и необязательные аргументы. Это справочное пособие снабжено массой полезных советов авторитетного автора и сотнями примеров программ с комментариями, благодаря которым они становятся понятными любому читателю независимо от уровня его подготовки. Книга рассчитана на широкий круг читателей, интересующихся программированием на C#.Введите сюда краткую аннотацию

Герберт Шилдт

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