《深入剖析ngx》—— 事件管理
1. 綜述
ngx 是事件驅動,沒有事件,ngx會一直阻塞在 epoll_wait 或 sigsuspend 上,ngx的事件有 IO事件,定時器事件。
2. 多路IO模型
ngx對多路複用IO進行了封裝。
封裝為 ngx_event_action_t 結構體,該結構體主要屬性為 回撥函式
為了方便使用,ngx定義了一些巨集
如此使用多路IO時,無需關心具體的IO介面,只需要用 ngx_add_event() 等
ngx繫結epoll到 ngx_event_action_t,就是 給 ngx_event_action_t 屬性賦值。
如此, ngx_event_action_t 就是 ngx_epoll_module_ctx.actions。
而呼叫這個 init 函式是在
其中 ecf->use 儲存 解析 配置檔案 use 指令獲得的值,若使用 use epoll ,則這裡 module 為 ngx_event_epoll_module,如此就呼叫了 ngx_event_epoll_module.init ,也就是綁定了 ngx_event_action_t 為 epoll.
所以我們得到如下框圖
3. epoll
介面如下
epoll有 LT 和 ET 模式,LT是預設工作模式,支援 no-block , block,ET 只支援 no-block,ET效率高,
為了避免 ET模式下,讀取所有資料,通常邏輯如下,
設定被監聽套接字為 no-block,加入epoll,
epoll_wait,得到事件,
讀取套接字,直到返回 EAGAIN(對於 面向包/令牌的檔案,比如資料包套接字介面,規範式終端)或是 read(),write()返回的資料長度小於請求的資料長度(對於面向流的檔案,比如pipe, FIFO,流套介面),才重新監聽epoll