本文会简单介绍 libuv 的事件循环,旨在入门级别的使用,而不作深刻探究,简单来讲就是,会大概用就行,先用熟练了,再去探究原理和源码函数
下图为官网的 libuv 的不一样部分及其涉及的子系统的图:oop
libuv 使用 handles 和 requests 来结合使用事件循环设计
handles 表示可以执行某些耗时的长时间存在的对象code
requests 表示短暂的操做,能够在一个 handles 上执行对象
下图为官网的事件循环:blog
这张图其实代表了 libuv 中的时间循环的处理过程,也就是 uv_run() 方法执行的过程,该方法内部是一个 while 循环:事件
上述步骤中,有三个句柄被重点标出,咱们就来讨论这三个句柄回调函数
idle handle 即空闲句柄,从上面流程图上能够看出,若是启动了 idle handle,每次事件循环的时候都会执行一遍其回调源码
该方法用于初始化 idle handlerequests
int uv_idle_init(uv_loop_t* loop, uv_idle_t* idle)
uv_idle_t 是 idle 句柄类型
该方法永远执行成功,返回值0
该方法用于开始 idle handle
int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb)
该方法用于都是执行成功的(返回值0),除非回调函数设置为 NULL(此时返回 UV_EINVAL)
回调函数声明以下:
void (*uv_idle_cb)(uv_idle_t* handle);
回调函数会把句柄带过去
该方法用于中止 idle handle
int uv_idle_stop(uv_idle_t* idle)
该方法永远执行成功,返回值0
执行以后,回调不会再执行
能够理解成准备句柄,从流程图中能够看出,在 idle 以后,在轮询 IO 以前执行其回调
其API和 idle 差很少
int uv_prepare_init(uv_loop_t* loop, uv_prepare_t* prepare);
初始化句柄,uv_prepare_t 为 prepare 句柄类型
返回值0,老是成功的
int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb);
开始句柄,执行老是成功的(返回0),除非回调函数为 NULL(此时返回 UV_EINVAL )
void (*uv_prepare_cb)(uv_prepare_t* handle);
int uv_prepare_stop(uv_prepare_t* prepare);
中止句柄,回调函数不会再执行
能够理解为检查句柄,若是程序中启动了 check 句柄,则在每次轮询 IO 以后执行其回调函数,正好和 prepare 先后呼应
这种设计的机制是 libuv 为用户预留的借口,在轮询 IO 循环状态先后进行准备和校验操做
其 API 和上面两种句柄相似
int uv_check_init(uv_loop_t* loop, uv_check_t* check);
初始化句柄,uv_check_t 为 check 句柄类型
方法执行老是成功的
int uv_check_start(uv_check_t* check, uv_check_cb cb);
开始句柄,回调函数能够为 NULL
方法执行老是成功的(返回0),除非回调函数为 NULL(返回UV_EINVAL )
void (*uv_check_cb)(uv_check_t* handle);
int uv_check_stop(uv_check_t* check);
中止句柄,回调函数不会再执行
方法执行老是成功的,返回0
#include <stdio.h> #include <stdlib.h> #include <uv.h> #define MAX_NUM 3 int count = 0; void idle_cb(uv_idle_t *handle) { count++; printf("idle handle callback, count = %d\n", count); if (count >= MAX_NUM) { printf("idle handle stop, count = %d\n", count); uv_stop(uv_default_loop()); } } void prepare_cb(uv_prepare_t *handle) { printf("prepare handle callback\n"); } void check_cb(uv_check_t *check) { printf("check handle callback\n"); } int main() { uv_idle_t idle; uv_prepare_t prepare; uv_check_t check; uv_idle_init(uv_default_loop(), &idle); uv_idle_start(&idle, idle_cb); uv_prepare_init(uv_default_loop(), &prepare); uv_prepare_start(&prepare, prepare_cb); uv_check_init(uv_default_loop(), &check); uv_check_start(&check, check_cb); uv_run(uv_default_loop(), UV_RUN_DEFAULT); return 0; }
输出结果以下:
idle handle callback, count = 1 prepare handle callback check handle callback idle handle callback, count = 2 prepare handle callback check handle callback idle handle callback, count = 3 idle handle stop, count = 3 prepare handle callback check handle callback
上例子中没有 IO 相关的代码,主要用于熟悉三种句柄回调函数的执行顺序