The OpenNET Project / Index page

[ новости/++ | форум | wiki | теги | ]

Краткое введение в kqueue/kevent. (freebsd kqueue select)


<< Предыдущая ИНДЕКС Правка src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: freebsd, kqueue, select,  (найти похожие документы)
From: Илья Воронин <http://www.ivoronin.pp.ru/>; Date: Mon, 28 Feb 2005 18:21:07 +0000 (UTC) Subject: Краткое введение в kqueue/kevent. Оригинал: http://www.zlug.pp.ru/book/view/164 kqueue предоставляет механизм уведомления процесса о некоторых событиях, произошедших в системе. Впервые этот интерфейс появился в FreeBSD 4.1 и на данный момент присутствует практически во всех BSD системах. (в Linux есть его аналог - epoll()). Как это работает: процесс с помощью вызова kqueue() получает дескриптор очереди сообщений ядра (в случае ошибки процесс завершается): if ( ( kq = kqueue() ) == -1 ) exit(1); затем с помощью kevent() устанавливает, сообщения о каких именно событиях он желает получать. Например, мы хотим знать когда файл (которому соотвествкует дескриптор fd) изменится: /* * Здесь: * ke - структура kevent. (EV_SET это просто макрос, который заполянет * её элементы. * fd - дескриптор файла, за изменениями которого мы хотим наблюдать. * EVFILT_VNODE - тип фильтра - в данном случае мы следим за vnode. * EV_ADD, EV_CLEAR - флаги, EV_ADD - добавить событие, EV_CLEAR - не * удалять событие из очереди, после первого его возникновения. * NOTE_WRITE - аргументы фильтра. Следить за записями в файл. * 0 - Какие-то дополнительные данные Smiling ) * NULL - тут можно указать любой указатель, ядро просто вернет его при * получении события. Как это можно использовать: допустим мы * следим за измением нескольких файлов, и перечитываем их при * надобности, - можно поместить сюда указатель наструктуру вида: * struct { * int fd; * char * pathname; * } kqfile; * и тогда при получении события, мы сможем быстро узнать - * какой именно файл изменился и тут же его перечитывать. */ EV_SET(&ke, fd, EVFILT_VNODE, EV_ADD|EV_CLEAR, NOTE_WRITE, 0, NULL); /* * Собственно сама регистрация события. */ if ( kevent(kq, &ke, 1, NULL, 0, NULL) == -1 ) exit(1); Как потом получать события: while(1) if ( kevent(kq, NULL, 0, &ke, 1, NULL) != -1 ) printf("A write occurred on the file.\n"); Функция kevent() в данном случае блокирует процесс до тех пор пока не наступит событие. (причём если мы задали несколько фильтров, можно по возвращенной структуре ke определить - какое именно событие произошло). Полный пример программы: #include <stdio.h> #include <stdlib.h> #include <err.h> #include <fcntl.h> #include <string.h> #include <sys/types.h> #include <sys/event.h> extern char * __progname; int main(int argc, char * argv[]){ int fd, kq; struct kevent ke; if ( argc < 2 ) errx(1,"usage: %s file",__progname); if ( ( fd = open(argv[1], O_RDONLY, NULL) ) == NULL ) err(1,"%s:%i",__FILE__,__LINE__); if ( ( kq = kqueue() ) == -1 ) err(1,"%s:%i",__FILE__,__LINE__); bzero(&ke,sizeof(ke)); EV_SET(&ke, fd, EVFILT_VNODE, EV_ADD|EV_CLEAR, NOTE_WRITE, 0, NULL); if ( kevent(kq, &ke, 1, NULL, 0, NULL) == -1 ) err(1,"%s:%i",__FILE__,__LINE__); bzero(&ke,sizeof(ke)); while(1) if ( kevent(kq, NULL, 0, &ke, 1, NULL) != -1 ) printf("A write occurred on the file.\n"); return 0; } Прошу прощения за сумбурность изложения =), Много информации можно найти в man kqueue. Сравнение BSD's kqueue() и Linux's epoll() - http://www.opennet.ru/base/dev/kqueue_vs_epoll.txt.html

<< Предыдущая ИНДЕКС Правка src Установить закладку Перейти на закладку Следующая >>

Обсуждение [ RSS ]
 
  • 1, Anton (??), 14:12, 22/02/2015 [ответить]    [к модератору]
  • +/
    Спасибо, прекрасно изложено.
     

    Ваш комментарий
    Имя:         
    E-Mail:      
    Заголовок:
    Текст:




      Закладки на сайте
      Проследить за страницей
    Created 1996-2017 by Maxim Chirkov  
    ДобавитьРекламаВебмастеруГИД  
    Hosting by Ihor