Introduction
libuv中的 loop 是 libuv 最为核心的事件队列. 在熟悉了 libuv 的高效事件队列 queue, 和基本数据结构 handle 之后, 就需要来了解一下 loop 的实现.
下面通过一个uvbook中具体的实例来讲解.
uv_loop_t 数据结构
我们首先看一下 uv_loop_t 的数据结构:
struct uv_loop_s {
/* User data - use this for whatever. */
void* data;
/* Loop reference counting. */
unsigned int active_handles;
void* handle_queue[2];
void* active_reqs[2];
/* Internal flag to signal loop stop. */
unsigned int stop_flag;
UV_LOOP_PRIVATE_FIELDS
};
其中 void *data
用来存放任意的用户数据, void *handle_queue[2]
就是 handle 的队列, 为什么用两个空指针来表示可以看我之前的源码剖析文章. void *active_reqs[2]
是 request 队列, stop_flag
表示是否运行, 在run和close的时候会观察这个变量.
再然后 UV_LOOP_PRIVATE_FIELDS
是用户不应该操纵的变量, 其中变量较多, 包括了很多队列: idle_handles
, pending_queue
, watcher_queue
等等, 这里就不列举出来了
举个例子
下面以一个较为简单的sample代码为例, 例子来源于 uvbook/code/idle-basic
, 稍稍修改了一下, 多加了一个idle_handle
#include <stdio.h>
#include <uv.h>
int64_t counter = 0;
void wait_for_a_while(uv_idle_t* handle) {
counter++;
if (counter >= 10e6)
uv_idle_stop(handle);
}
void do_something(uv_idle_t* handle){
printf("Do something\n");
uv_idle_stop(handle);
}
int main() {
uv_idle_t idler;
uv_idle_t idler2;
uv_idle_init(uv_default_loop(), &i