本文會簡單介紹 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 相關的代碼,主要用於熟悉三種句柄回調函數的執行順序