`
Zhongwei_leg
  • 浏览: 557405 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

调用 kqueue 接口的示例代码

 
阅读更多

了解一个接口,最好的方式莫过于亲手去测试,所以直接上示例代码:

代码来自 kqueue - NetBSD System Calls Manual

这段代码的主要功能是,监控一个指定文件,并打印出收到的事件消息。(文件由程序的第一个运行参数指定)

 

 

monitor.h

 

#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <err.h>

int main(int argc, char *argv[])
{
  int fd, kq, nev;
  struct kevent ev;
  static const struct timespec tout = { 1, 0 };

  if ((fd = open(argv[1], O_RDONLY)) == -1)
    err(1, "Cannot open `%s'", argv[1]);

  if ((kq = kqueue()) == -1)
    err(1, "Cannot create kqueue");

  EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR,
	 NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK|
	 NOTE_RENAME|NOTE_REVOKE, 0, 0);

  if (kevent(kq, &ev, 1, NULL, 0, &tout) == -1)
    err(1, "kevent");

  for (;;) {
    nev = kevent(kq, NULL, 0, &ev, 1, &tout);
    if (nev == -1)
      err(1, "kevent");
    if (nev == 0)
      continue;
    if (ev.fflags & NOTE_DELETE) {
      printf("deleted ");
      ev.fflags &= ~NOTE_DELETE;
    }
    if (ev.fflags & NOTE_WRITE) {
      printf("written ");
      ev.fflags &= ~NOTE_WRITE;
    }
    if (ev.fflags & NOTE_EXTEND) {
      printf("extended ");
      ev.fflags &= ~NOTE_EXTEND;
    }
    if (ev.fflags & NOTE_ATTRIB) {
      printf("chmod/chown/utimes ");
      ev.fflags &= ~NOTE_ATTRIB;
    }
    if (ev.fflags & NOTE_LINK) {
      printf("hardlinked ");
      ev.fflags &= ~NOTE_LINK;
    }
    if (ev.fflags & NOTE_RENAME) {
      printf("renamed ");
      ev.fflags &= ~NOTE_RENAME;
    }
    if (ev.fflags & NOTE_REVOKE) {
      printf("revoked ");
      ev.fflags &= ~NOTE_REVOKE;
    }
    printf("\n");
    if (ev.fflags)
      warnx("unknown event 0x%x\n", ev.fflags);
  }
}

 

编译,并生成一个用于测试的待监控文件, 然后运行程序。

 

 

cc monitor.c -o monitor
touch zhongwei.log
./monitor zhongwei.log

 

对该文件进行各种操作,观察输出:

 

 

echo "Hello kqueue" >> zhongwei.log
# 输出为:
# extended 
# written 

touch zhongwei.log
# 输出为:
# chmod/chown/utimes

mv zhongwei.log zhongwei2.log
# 输出为:
# renamed 

rm zhongwei2.log 
# 输出为:
# deleted hardlinked
 

监控效果很好,很强大。看一下代码:

 

 

struct kevent ev;
 

在该示例中,结构体 kevent 用来描述待监测文件(例如,对应的 file descriptor, 需要监控的事件)。

 

 

struct kevent {
             uintptr_t ident;        /* identifier for this event */
             uint32_t  filter;       /* filter for event */
             uint32_t  flags;        /* action flags for kqueue */
             uint32_t  fflags;       /* filter flag value */
             int64_t   data;         /* filter data value */
             intptr_t  udata;        /* opaque user data identifier */
     };

 

结构体初始化操作呢?原来在这里:

 

 

EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR,
	 NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK|
	 NOTE_RENAME|NOTE_REVOKE, 0, 0);
 

EV_SET 是一个宏定义,用于简化 kevent 结构体的初始化代码。

在 event.h 中可以看到 EV_SET  的定义,这个文件位于 (系统:Mac OS X 10.6.8)

 

$ find /System/ -name event.h
/System//Library/Frameworks/Kernel.framework/Versions/A/Headers/sys/event.h
  
#define EV_SET(kevp, a, b, c, d, e, f) do { \
    struct kevent *__kevp__ = (kevp);   \
    __kevp__->ident = (a);          \
    __kevp__->filter = (b);         \
    __kevp__->flags = (c);          \
    __kevp__->fflags = (d);         \
    __kevp__->data = (e);           \
    __kevp__->udata = (f);          \
} while(0)
 

现在需要仔细看一下,结构体 kevent 各成员的含义 (括号内为示例代码中传入的实际参数):

ident (fd)

事件的标识,通常使用 file descriptor 来标识。

其他值还有 EVFILT_AIO, EVFILT_SIGNAL 等。

 

filter (EVFILT_VNODE

指定用来处理该事件的 kernel filter. 通常是系统预定义的 kernel filter.

EVFILT_VNODE 说明要监控一个文件,具体需要监控的事件类型在 fflags 中指定。

 

flags  (EV_ADD | EV_ENABLE | EV_CLEAR)

Actions to perform on the event.

例如:EV_ADD 是将该事件加入 kqueue;

EV_ENABLE 是允许 kevent() 函数返回该事件,当其触发时。

 

 

fflags (NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK|NOTE_RENAME|NOTE_REVOKE)

Filter-specific flags.

 

data  (0)

Filter-specific data value.

 

udata  (0)

Opaque user-defined value passed through the kernel unchanged.

 

详细信息查看 man kqueue 就行。

 

 

参考文档:

1。kqueue - NetBSD System Calls Manual

 

分享到:
评论

相关推荐

    ace技术内幕示例代码

    "ACE技术内幕示例代码"是针对ACE(Adaptive Communication Environment)框架的一本书中的实践代码集,主要适用于Linux操作系统。ACE是一个开源的、跨平台的C++库,它提供了多种网络通信和并发处理的工具,广泛应用...

    bsd kqueue

    为了更好地理解Kqueue如何应用于实际项目中,下面是一个简单的示例代码片段,展示了如何使用Kqueue来监控文件描述符的读写事件。 ```c #include #include #include int main(void) { int kq, ev; struct ...

    c-event-machine:基于 Linux epoll 或 FreeBSD kqueue 的简单低级事件机

    6. **源码结构分析**: “c-event-machine-master”可能表示这是一个开源项目的主要分支,包含源代码和可能的示例。用户可以通过查看源代码了解其内部实现,学习如何使用epoll或kqueue构建自己的事件驱动程序。 7. *...

    libevent-2.1.8-stable(源码库).zip

    - **更多文档**:这个版本提供了更丰富的文档,包括API参考手册和示例代码,帮助开发者更好地理解和使用libevent。 5. **学习与实践** - **阅读源码**:libevent-2.1.8-stable的源码库包含了大量的示例代码和测试...

    libevent-book

    10. **示例代码** `libevent-book`可能包含了丰富的示例代码,帮助开发者理解libevent的用法,包括基本的网络连接、HTTP服务器实现、定时任务等。 通过学习《libevent-book》,开发者不仅可以掌握libevent的基本...

    boost asio c++ network programming code

    Boost.Asio是C++库中的一个强大工具,用于进行异步网络编程,它提供了一种高效、简洁的方式来处理I/O操作,包括TCP、UDP、套接字和...这些示例代码涵盖了从基础到高级的各种用法,是学习和实践C++网络编程的宝贵资源。

    cpp-简洁易用的C11网络库支持单机千万并发连接

    9. **示例与测试**:库可能包含示例代码和单元测试,帮助用户快速理解如何使用并验证其功能。 10. **性能测试**:可能有基准测试或压力测试,以证明其在高并发场景下的稳定性和效率。 总之,这个C++11网络库是为了...

    Linux下的libevent-2.0.22-stable

    5. **文档更新**:提供了更完善的文档,包括API参考、示例代码和使用指南,帮助开发者更好地理解和使用libevent。 在解压的文件`libevent-2.0.22-stable`中,通常会包含源代码、编译脚本、文档、示例程序等内容。...

    libevent.zip_libevent

    压缩包中的“libevent”可能包含了一些示例代码和测试用例,这些可以帮助开发者了解如何使用libevent库。通常,这些测试用例会涵盖libevent的各种功能,如基本的网络连接、定时器事件、信号处理等,是学习和调试...

    跨平台socket封装

    7. **示例和测试**:为了方便开发者理解和使用,封装库通常会包含示例代码和完整的测试用例,确保在各种环境下的正确性和兼容性。 文件名为“socket_wrapper”的压缩包很可能包含了这样一个跨平台socket封装的源码...

    libevent-release-1.4.14b-stable.tar.gz

    libevent还提供了丰富的示例代码,帮助开发者快速上手。在解压后的libevent-release-1.4.14b-stable目录中,可以看到examples子目录,其中包含了多种应用场景的示例程序,如echo_server、http_server等,这些都是...

    基于select模型的socket服务器

    在给定的文件中,"Client"可能是客户端示例代码,用于模拟与服务器的交互,测试服务器功能。而"SelectServer"则是服务器端的实现,包含了上述步骤的代码逻辑。 在实际应用中,虽然select模型简单易用,但存在一些...

    LibEvent中文帮助文档_zhouyongyi

    7. **示例代码**:提供各种示例程序,演示如何使用LibEvent构建一个简单的HTTP服务器、TCP服务器等。 8. **故障排查与优化**:讲解遇到问题时如何调试,以及如何优化LibEvent的性能,例如调整事件调度算法、减少上...

    开源项目-golang-go.zip

    在压缩包中的"go-master"目录可能包含了该项目的源代码仓库,其中可能包括了对`net`包的修改、测试案例、提案的详细文档以及相关的示例代码。通过阅读这些源码,开发者可以学习到如何在Go语言中实现和优化网络连接的...

    cpp-Pistache是一个现代而优雅的C的HTTP和REST框架

    8. **文档与社区支持**:Pistache项目提供详尽的文档,包括API参考和示例代码,同时有一个活跃的社区,可以解答使用过程中遇到的问题。 9. **跨平台**:Pistache可以在多种操作系统上运行,包括Linux、macOS和...

    uWebSockets-19.3.0_y21m6.zip

    在压缩包文件名称列表中,"uWebSockets-19.3.0"很可能是源代码的顶层目录,包含了头文件、源文件、示例代码、构建脚本等。开发者可以通过解压这个文件,根据提供的README或其他文档来编译和运行uWebSockets。 总的...

    socket编程之并发服务器连接代码

    五、示例代码 服务器端代码可能包含以下关键步骤: ```python import socket import threading def handle_client(client_socket): # 处理客户端请求 request = client_socket.recv(1024) response = "Hello, ...

    最新libevent

    此外,社区还提供了一系列示例代码和教程,帮助快速上手。 为了使用libevent-2.0.17-stable,开发人员首先需要解压下载的压缩包,然后按照提供的编译指示进行配置、编译和安装。在源代码中,通常会有一个名为`...

    libevent libevent-2.1.8-stable.tar.gz

    8. **丰富的文档和示例**:官方提供了详尽的API文档和示例代码,帮助开发者快速上手。 在实际开发中,利用Libevent可以构建出高并发、低延迟的网络服务,例如WebSocket服务器、实时聊天系统、流媒体服务等。通过...

    libevent网络库

    在 `serverp.cpp`、`server.cpp` 和 `client.cpp` 文件中,我们可能看到了如何创建网络服务器和客户端的示例。通常,服务器会创建一个监听套接字,并将其绑定到一个端口,然后调用 `event_assign()` 或 `event_base_...

Global site tag (gtag.js) - Google Analytics