使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// 只需导入单个头文件
#include <ev.h>
#include <stdio.h>

// I/O 观察者
ev_io stdin_watcher;

// Timer 观察者
ev_timer timeout_watcher;

// 当stdin可读的时候, 这个回调将会被触发.
static void stdin_cb (EV_P_ ev_io *w, int revents)
{
puts ("stdin ready");

// 如果你只需要获得一次事件, 那么需要主动停止事件观察者.
ev_io_stop (EV_A_ w);

// 调用此方法后, 会让ev_run停止所有事件.
ev_break (EV_A_ EVBREAK_ALL);
}

// 当超时时间到达, 这个回调将会被触发.
static void timeout_cb (EV_P_ ev_timer *w, int revents)
{
puts ("timeout");

// 调用此方法后, 会让ev_run停止所有事件.
ev_break (EV_A_ EVBREAK_ONE);
}

int main (void)
{
// 可以使用已定义的宏来获取默认的事件循环, 当然你也可以根据自己的需求创建指定的.
struct ev_loop *loop = EV_DEFAULT;

// 在启动一个I/O观察者之前, 我们需要先初始化它.
ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ);
// 启动后意味着观察者将在`stdin`变为可读后触发.
ev_io_start (loop, &stdin_watcher);

// 在启动一个Timer观察者之前, 我们需要先初始化它.
ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.);
// 这个一次性定时器将会从启动开始后的`5.5`秒后超时触发.
ev_timer_start (loop, &timeout_watcher);

// 开始运行事件循环
ev_run (loop, 0);

// 如果事件循环退出, 那将会执行到这里.
return 0;
}

示例讲解

在示例代码的1~3行导入了本章示例所需要的头文件.

在第35行我们通过Libev的宏获的了一个缺省的ev_loop对象.

随后的43~51行之间分别注册了ev_ioev_timer2个事件. 注册这2个事件的实际含义为:

  • 5.5秒内ev_timer将必然会超时退出;

  • stdin输入任意字符后按Enter键退出.

我们在48行调用ev_run进入循环等待事件发生. 用户输入字符后或超时到期调用20行或29行的ev_break退出事件循环.

ev_run函数最终返回, 进程也在此执行完毕退出. 终端最终输出timeoutstdin ready.