Интерфейс kqueue

Интерфейс kqueue

Система FreeBSD версии 4.1 предложила сетевым программистам новый интерфейс, получивший название kqueue. Этот интерфейс позволяет процессу зарегистрировать фильтр событий, описывающий интересующие данный процесс события kqueue. К событиям этого типа относятся операции ввода-вывода с файлами и тайм-ауты, а также асинхронный ввод-вывод, уведомление об изменении файлов и обработка сигналов.

#include <sys/types.h>

#include <sys/event.h>

#include <sys/time.h>

int kqueue(void);

int kevent(int kq, const struct kevent *changelist, int nchanges,

 struct kevent *eventlist, int nevents, const struct timespec *timeout);

void EV_SET(struct kevent *kev, uintptr_t ident, short filter,

 u_short flags, u_int fflags, intptr_t data, void *udata);

Функция kqueue возвращает новый дескриптор kqueue, который может использоваться в последующих вызовах kevent. Функция kevent применяется для регистрации интересующих событий, а также для получения уведомлений об этих событиях. Параметры changelist и nchanges описывают изменения в предыдущем варианте списка событий. Если nchanges отлично от нуля, выполняются все запрошенные в структуре changelist изменения. Функция kevent возвращает количество событий или нуль, если произошел выход по тайм-ауту. В аргументе timeout хранится значение тайм-аута, обрабатываемое подобно тому, как при вызове select (NULL для блокирования, ненулевое значение для задания конкретного тайм- аута, а нулевое значение трактуется как необходимость неблокирующего вызова). Обратите внимание, что параметр timeout имеет тип struct timespec, отличающийся от struct timeval в вызове select тем, что первый имеет наносекундное разрешение, а второй — микросекундное.

Структура kevent определяется в заголовочном файле <sys/event.h>:

struct kevent {

 uintptr_t ident;  /* идентификатор (например, дескриптор файла) */

 short     filter; /* тип фильтра (например, EVFILT_READ) */

 u_short   flags;  /* флаги действий (например, EV_ADD); */

 u_int     fflags; /* флаги, относящиеся к конкретным фильтрам */

 intptr_t  data;   /* данные, относящиеся к конкретным фильтрам */

 void      uidata; /* непрозрачные пользовательские данные */

};

Действия по смене фильтра и флаговые возвращаемые значения приведены в табл. 14.5.

Таблица 14.5. Флаги для операций kevent

Значение flags Описание Изменяется Возвращается
EV_ADD Добавить новое событие, подразумевается по умолчанию, если не указан флаг EV_DISABLE
EV_CLEAR Сброс состояния события после считывания его пользователем
EV_DELETE Удаление события из фильтра
EV_DISABLE Отключение события без удаления его из фильтра
EV_ENABLE Включение отключенного перед этим события
EV_ONESHOT Удаление события после его однократного срабатывания
EV_EOF Достигнут конец файла
EV_ERROR Произошла ошибка, код errno записан в поле data

Типы фильтров приведены в табл. 14.6.

Таблица 14.6. Типы фильтров

Значение filter Описание
EVFILT_AIO События асинхронного ввода-вывода
EVFILT_PROC События exit, fork, exec для процесса
EVFILT_READ Дескриптор готов для чтения (аналогично select)
EVFILT_SIGNAL Описание сигнала
EVFILT_TIMER Периодические или одноразовые таймеры
EVFILT_VNODE Изменение и удаление файлов
EVFILT_WRITE Дескриптор готов для записи (аналогично select)

Перепишем функцию str_cli из листинга 6.2 так, чтобы она использовала kqueue. Результат представлен в листинге 14.8.

Листинг 14.8. Функция str_cli, использующая kqueue

//advio/str_cli_kqueue04.c

 1 #include "unp.h"

 2 void

 3 str_cli(FILE *fp, int sockfd)

 4 {

 5  int kq, i, n, nev, stdineof = 0, isfile;

 6  char buf[MAXLINE];

 7  struct kevent kev[2];

 8  struct timespec ts;

 9  struct stat st;

10  isfile = ((fstat(fileno(fp), &st) 0) &&

11   (st.st_mode & S_IFMT) == S_IFREG);

12  EV_SET(&kev[0], fileno(fp), EVFILT_READ, EV_ADD, 0, 0, NULL);

13  EV_SET(&kev[1], sockfd, EVFILT_READ, EV_ADD, 0, 0, NULL);

14  kq = Kqueue();

15  ts.tv_sec = ts.tv_nsec = 0;

16  Kevent(kq, kev, 2, NULL, 0, &ts);

17  for (;;) {

18   nev = Kevent(kq, NULL, 0, kev, 2, NULL);

19   for (i = 0; i < nev; i++) {

20    if (kev[i].ident == sockfd) { /* сокет готов для чтения */

21     if ((n = Read(sockfd, buf, MAXLINE)) == 0) {

22      if (stdineof == 1)

23       return; /* нормальное завершение*/

24      else

25       err_quit("str_cli: server terminated prematurely");

26     }

27     Write(fileno(stdout), buf, n);

28    }

29    if (kev[i].ident == fileno(fp)) { /* входной поток готов к чтению */

30     n = Read(fileno(fp), buf, MAXLINE);

31     if (n > 0)

32      Writen(sockfd, buf, n);

33     if (n == 0 || (isfile && n == kev[i].data)) {

34      stdineof = 1;

35      Shutdown(sockfd, SHUT_WR); /* отправка FIN */

36      kev[i].flags = EV_DELETE;

37      Kevent(kq, &kev[i], 1, NULL, 0, &ts); /* удаление

                                                 kevent */

38      continue;

39     }

40    }

41   }

42  }

43 }

Проверка, указывает ли дескриптор на файл

10-11 Поведение kqueue при достижении конца файла зависит от того, связан ли данный дескриптор с файлом, каналом или терминалом, поэтому мы вызываем fstat, чтобы убедиться, что мы работаем с файлом. Эти сведения понадобятся позже.

Настройка структур kevent для kqueue

12-13 При помощи макроса EV_SET мы настраиваем две структуры kevent. Обе содержат фильтр событий готовности к чтению (EVFILT_READ) и запрос на добавление этого события к фильтру (EV_ADD).

Создание kqueue и добавление фильтров

14-16 Мы вызываем kqueue, чтобы получить дескриптор kqueue, устанавливаем тайм- аут равным нулю, чтобы сделать вызов kevent неблокируемым, и наконец, вызываем kevent с массивом kevent на месте соответствующего аргумента.

Бесконечный цикл с блокированием в kevent

17-18 Мы входим в бесконечный цикл и блокируемся в kevent. Функции передается пустой список изменений, потому что все интересующие нас события уже зарегистрированы, и нулевой тайм-аут, что позволяет заблокироваться навечно.

Перебор возвращаемых событий в цикле

19 Мы проверяем все возвращаемые события и обрабатываем их последовательно.

Сокет готов для чтения

20-28 Эта часть кода ничем не отличается от листинга 6.2.

Вход готов для чтения

29-40 Код практически аналогичен листингу 6.2 за тем отличием, что нам приходится обрабатывать конец файла, возвращаемый kqueue. Для каналов и терминалов kqueue возвращает событие готовности дескриптора к чтению, подобно select, так что мы можем считать из этого дескриптора символ конца файла. Для файлов kqueue возвращает количество байтов, оставшихся в поле data структуры struct kevent и предполагает, что приложение само определит, когда оно доберется до конца этих данных. Поэтому мы переписываем цикл таким образом, чтобы отправлять данные по сети, если они были считаны из дескриптора. Затем проверяется достижение конца файла: если мы считали нуль байтов или если мы считали все оставшиеся байты из дескриптора файла, значит, это и есть EOF. Еще одно изменение состоит в том, что вместо FD_CLR для удаления дескриптора из набора файлов мы используем флаг EV_DELETE и вызываем kevent для удаления события из фильтра в ядре.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Интерфейс

Из книги Microsoft Office автора Леонтьев Виталий Петрович

Интерфейс На самом деле Word – это не просто текстовый редактор (то есть, программа, предназначенная для создания и обработки текстов), а нечто гораздо большее. С помощью Word вы можете не просто набрать текст, но и оформить его по своему вкусу: включить в него таблицы и


Интерфейс

Из книги Windows Vista автора Леонтьев Виталий Петрович

Интерфейс ИНТЕРФЕЙС, графическая «оболочка», с помощью которой мы, пользователи, обращаемся к операционной системе. Интерфейс – это посредник, переводчик, задача которого преобразовать все внутренние «рычаги управления» Windows в понятную людям графическую


Интерфейс

Из книги Мобильный интернет автора Леонтьев Виталий Петрович

Интерфейс Spb Pocket Plus! Страница программы: http://www.spbsoftwarehouse.comСтатус: Shareware, $15Вам не кажется, что место на стартовом экране Windows Mobile можно было бы использовать куда рациональнее? Во всяком случае, у крупнейшей российской фирмы по производству мобильного софта такое ощущение


Веб-интерфейс

Из книги Работа на ноутбуке автора Садовский Алексей

Веб-интерфейс Существует еще один способ получения и отправки писем – это веб-интерфейс. Он работает через любой браузер. Его главное преимущество заключается в том, что вы сможете забрать свою почту с абсолютно любого компьютера без настройки почтового клиента.Кроме


Интерфейс

Из книги Photoshop. Мультимедийный курс автора Мединов Олег

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


Интерфейс

Из книги Pinnacle Studio 11 автора Чиртик Александр Анатольевич

Интерфейс Пример внешнего вида Pinnacle Studio в режиме захвата приведен на рис. 2.1. Рис. 2.1. Studio в режиме захватаВ случае, показанном на рисунке, захват осуществляется с цифровой камеры. Поэтому в левой нижней части окна присутствует панель управления камерой (Контроллер


7.2 Интерфейс WMI

Из книги Серверные технологии хранения данных в среде Windows® 2000 Windows® Server 2003 автора Дайлип Наик

7.2 Интерфейс WMI Как уже отмечалось, модель CIM определена в рабочей группе DMTF и принята к использованию ассоциацией SNIA. Интерфейс WMI представляет собой реализацию модели CIM от Microsoft. Другими словами, WMI – это «CIM для Windows».Интерфейс WMI был разработан для режима ядра и


27.1. Интерфейс dl

Из книги Разработка приложений в среде Linux. Второе издание автора Джонсон Майкл К.

27.1. Интерфейс dl Процесс динамической загрузки заключается в открытии библиотеки, поиске любого количества символов, обработке любых возникающих ошибок и закрытии библиотеки. Все функции динамической загрузки объявляются в одном заголовочном файле, <dlfcn.h>, и


Веб-интерфейс

Из книги Интернет – легко и просто! автора Александров Егор

Веб-интерфейс Работа с почтой непосредственно на том сайте, где вы зарегистрировали свой почтовый ящик, называется работой с помощью веб-интерфейса (рис. 5.2). Рис. 5.2. Работа с помощью веб-интерфейса.Для доступа к почтовому ящику посредством веб-интерфейса достаточно зайти


4.1. Интерфейс с PHP

Из книги MySQL 5.0. Библиотека программиста автора Гольцман Виктор Иосифович

4.1. Интерфейс с PHP В этом разделе мы рассмотрим процесс создания веб-приложения на языке PHP, взаимодействующего с базой данных MySQL. Вначале познакомимся с платформами, на которых возможно создание такого приложения, а затем с функциями языка PHP, обеспечивающими работу с


Интерфейс TPI

Из книги Операционная система UNIX автора Робачевский Андрей М.

Интерфейс TPI


Интерфейс

Из книги Установка, настройка и восстановление Windows 7 на 100% автора Ватаманюк Александр Иванович

Интерфейс Интерфейс Windows 7 не претерпел каких-либо особых изменений по сравнению с внешним видом Windows Vista. Тем не менее кое-что новое в нем также имеется. Основные изменения коснулись оформления таких элементов и программ, как меню Пуск, Панель задач, область уведомлений,


Интерфейс

Из книги Секреты приложений Google автора Балуев Денис

Интерфейс …И видим, что на экране вместо обещанных красот спутниковой разведки – обычная карта земной поверхности со знакомыми по школьным атласам и контурным картам схемами континентов! Да, судя по схеме, мы с вами находимся где-то в европейской части России


Интерфейс

Из книги Как приручить компьютер за несколько часов автора Ремнева Ирина

Интерфейс Интерфейс (внешний вид) программы очень схож с Microsoft Word. После запуска программы экран Excel содержит пять областей (по порядку сверху вниз): Внешний вид окна программы ExcelКак вы теперь смогли сами убедиться, основным отличием от Word является присутствие вместо


Интерфейс

Из книги Введение в написание скриптов на Питоне для Блендера 2.5x. Примеры кода автора Larsson Thomas