Libev 官方文档学习笔记(2)——watcher 基础
请注意这是 libev 而不是 libevent 的文章!
这篇文章是第二篇,主要讲 libev 里的 watcher 的一些基础操作。
本文地址:https://segmentfault.com/a/1190000006200077
Watcher 解析
以下是一段示意性的代码,使用的是ev_io:
static void my_cb (struct ev_loop *loop, ev_io *w, int revents){ ev_io_stop (w); ev_break (loop, EVBREAK_ALL);}some_main(){ ... struct ev_loop *loop = ev_default_loop (0); ev_io stdin_watcher; ev_init (&stdin_watcher, my_cb); ev_io_set (&stdin_watcher, STDIN_FILENO, EV_READ); ev_io_start (loop, &stdin_watcher); ev_run (loop, 0); ...}
每一个 watcher 类型有一个附属的 watcher 结构体。(一般是struct ev_XXX或ev_XXX)
每一个 watcher 结构都需要用ev_init初始化,每一个 watcher 都有对应的ev_XXX_set函数、ev_XXX_start函数、ev_XXX_stop函数。在 ev_run 之前进行各个 watcher 的 ev_start。
只要 watcher 是 active,就不能再调用 init。
每个 callback 都有三个参数:loop, watcher, 事件的掩码值。可能的掩码值有:
EV_READ
EV_WRITE
EV_TIMER:ev_timer 超时
EV_PERIODIC:ev_periodic 超时
EV_SIGNAL:某线程接收了 ev_signal 中指定的 signal
EV_CHILD:ev_child 中指定的 pid 获得了一个状态变化
EV_STAT:ev_stat 中指定的 path 的属性修改了
EV_IDLE:ev_idle watcher 发现无事可做
EV_PREPARE, EV_CHECK:所有 ev_prepare watchers 在 loop 开始收集事件前调用;所有ev_check watchers 则在以后调用。回调可在这两个 watchers 中开始/停止相应的 watchers。
EV_EMBED:ev_embed watcher
EV_CLEANUP:event loop 即将被销毁
EV_ASYNC:asuny watcher 已经被异步通知
EV_CUSTOM:不是 libev 发送的信号。参见ev_feed_event
EV_ERROR:在 libev 内存不够用时可能产生;fd 被外部关闭时也可能产生
通用 watcher 函数
void ev_init (ev_TYPE *watcher, callback)
使用这个宏初始化 watcher。此外还需要调用相应的 ev_XXX_set 函数。参见下文:
void ev_TYPE_set (ev_TYPE *watcher, [args])
设置指定类型的 wetaher。init 函数必须在此之前被调用一次,此后可以设置任意次的 set 函数。
不能对一个 active 的 watcher 调用此函数,但 pending 可以。比如:
ev_io w;
ev_init (&w, my_cb);
ev_io_set (&w, STDIN_FILENO, EV_READ);
void ev_TYPE_set (ev_TYPE *watcher, callback, [args])
这个宏将 init 和 set 糅合在一起使用
void ev_TYPE_start (loop, ev_TYPE *watcher)
开始(激活)指定的 watcher。如果 watcher 已经是 active,则调用无效。
void ev_TYPE_stop (loop, ev_TYPE *watcher)
停止 watcher,并清空 pending 状态。如果要释放一个 Watcher,最好都显式地调用 stop。
bool ev_is_active (ev_TYPE *watcher)
如果 watcher 被执行了一次 start,并且未被 stop,则返回 true。
bool ev_is_pending (ev_TYPE *watcher)
当且仅当 watcher pending 时返回 true。(如:有未决的事件,但是 callback 未被调用)
callback ev_cb (ev_TYPE *watcher)void ev_set_cb (ev_TYPE *watcher, callback)
读 / 写 callback
void ev_set_priority (ev_TYPE *watcher, int priority)int ev_priority (ev_TYPE *watcher)
Priority 是一个介于EV_MAXPRI(默认2)和EV_MIN_PRI(默认-2)之间的值。数值越高越优先被调用。但除了 ev_idle,每一个 watcher 都会被调用。
当 watcher 是 active 或 pending 时并不能修改。
实际上 priority 大于-2到2的范围也是没问题的。
void ev_invoke (loop, ev_TYPE *watcher, int revents);
使用指定的参数调用 callback
int ev_clear_pending (loop, ev_TYPE *watcher);
清除指定 watcher 的 pending 状态,并且返回 revents 位。如果 watcher 不是 pending 则返回0
void ev_feed_event (loop, ev_TYPE *watcher, int revents)
模拟一个事件。参见ev_feed_fd_event和ev_feed_signal_event
Watcher 状态
除了前文提及的 active 和 pending 状态之外,本小节描述了更加详细的 watcher 状态。
initialized:通过调用ev_TYPE_init对 watcher 进行初始化,这是注册到 loop 之前的必要步骤。可以再次调用 ev_TYPE_init 进行操作。
started/running/active:调用ev_TYPE_start之后的状态,并且开始等待事件。在这个状态下,除了特别提及的少数情况之外,它不能存取、移动、释放,只能维持着对它的指针。
pending:当 watcher 是 active 并且一个让 watcher 感兴趣的事件到来,那么 watcher 进入 pending。这个状态的 watcher 可以 access,但不能存取、移动、释放。
stopped:调用ev_TYPE_stop,此时状态与 initialized 相同。
系列篇
Libev 官方文档学习笔记(1)——概述和 ev_loop
Libev 官方文档学习笔记(2)——watcher 基础(本文)
Libev 官方文档学习笔记(3)——常用 watcher 接口(未完成)
使用 libev 构建 TCP 响应服务器的简单流程(未完成)
关键字:c, 异步编程, 异步io, linux
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!