Skip to content

1. BSD kqueue 编程:介绍

[BSD kqueue 编程指南:目录]

BSD kqueue 是类 BSD 操作系统中的内核事件通知机制,在所有的类 BSD 操作系统中都可以得到。类 BSD 操作系统包括 FreeBSD, NetBSD, OpenBSD 以及从这三大操作系统演化而来的各种分支。
点击放大:BSD kqueue 手册 (man kqueue)
BSD kqueue 手册 (man kqueue)

要阅读 BSD kqueue 正式文档,可以在任意一个类 BSD 操作系统命令行终端敲入 man kqueue 命令即可阅读。kqueue API 可免费的得到,继承一贯的 BSD 宽松许可证协议。

kqueue API 简单而强大,它只有两个函数 (kqueue(), kevent())、一个宏(EV_SET())、一个结构体(struct kevent)。然而结合 BSD 系统调用,却变成了轻便强大的秘密武器。

• 1. int kqueue(void);

The kqueue() system call provides a generic method of notifying the user when an event happens or a condition holds, based on the results of small pieces of kernel code termed filters. A kevent is identified by the (ident, filter) pair; there may only be one unique kevent per kqueue.

The filter is executed upon the initial registration of a kevent in order to detect whether a preexisting condition is present, and is also executed whenever an event is passed to the filter for evaluation. If the filter determines that the condition should be reported, then the kevent is placed on the kqueue for the user to retrieve.

The filter is also run when the user attempts to retrieve the kevent from the kqueue. If the filter indicates that the condition that triggered the event no longer holds, the kevent is removed from the kqueue and is not returned.

Multiple events which trigger the filter do not result in multiple kevents being placed on the kqueue; instead, the filter will aggregate the events into a single struct kevent. Calling close() on a file descriptor will remove any kevents that reference the descriptor.

The kqueue() system call creates a new kernel event queue and returns a descriptor. The queue is not inherited by a child created with fork(2). However, if rfork(2) is called without the RFFDG flag, then the descriptor table is shared, which will allow sharing of the kqueue between two processes.

• 2. struct kevent

The kevent structure is defined as:

struct kevent {
  uintptr_t ident;  /* identifier for this event */
  short     filter; /* filter for event */
  u_short   flags;  /* action flags for kqueue */
  u_int     fflags; /* filter flag value */
  intptr_t  data;   /* filter data value */
  void      *udata; /* opaque user data identifier */

• 3. EV_SET(kev, ident, filter, flags, fflags, data, udata);

The EV_SET() macro is provided for ease of initializing a kevent structure.

• 4. int kevent(int kq, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout);

The kevent() system call is used to register events with the queue, and return any pending events to the user. The changelist argument is a pointer to an array of kevent structures, as defined in . All changes contained in the changelist are applied before any pending events are read from the queue. The nchanges argument gives the size of changelist. The eventlist argument is a pointer to an array of kevent structures. The nevents argument determines the size of eventlist. When nevents is zero, kevent() will return immediately even if there is a timeout specified unlike select(2). If timeout is a non-NULL pointer, it specifies a maximum interval to wait for an event, which will be interpreted as a struct timespec. If timeout is a NULL pointer, kevent() waits indefinitely. To effect a poll, the timeout argument should be non-NULL, pointing to a zero-valued timespec structure. The same array may be used for the changelist and eventlist.

[BSD kqueue 编程指南:目录]






回复显示方式 直线程 | 分线程





Form options