菜鳥學習nginx之事件模組epoll(2)

2021-09-03 01:37:11 字數 2406 閱讀 9176

nginx封裝了新增/刪除事件介面:

#define ngx_add_event ngx_event_actions.add

#define ngx_del_event ngx_event_actions.del

/**

* 新增事件到事件驅動epoll中

* @param ev 事件物件

* @param event 事件型別

* 取值為 ngx_read_event ngx_write_event

* @param flags

*/static ngx_int_t

ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)

else

if (e->active)

else

看到估計有很多人和我一樣很困惑,為什麼註冊的事件明明是讀(寫)事件卻獲取寫(讀)事件物件?

說明:epoll模型有乙個特點:

對於乙個全新的socket要註冊到epoll中,操作型別為epoll_ctl_add。

對於已經新增到epoll中的socket,若要對其進行修改只能使用epoll_ctl_mod,不能使用epoll_ctl_add,否則會報錯。

那麼如何判斷當前fd是否已經新增到epoll中呢?nginx使用上面方式:

1、對於乙個socket來說,可以向epoll同時註冊讀和寫兩種事件。所以nginx在處理註冊事件時,這樣判斷的,如果新註冊的事件是讀事件,則取出對應的寫事件作為目標事件,反之亦然。

2、判斷目標事件是否為active,當目標事件active為1表示當前事件已經在epoll中,那麼我們就程序mod操作否則進行add操作。這裡需要知曉,新註冊的事件active一定是0。

/**

* 1、設定event事件

* 2、設定私有資料字段,當事件發生後epoll_wait會帶回該欄位。上層應用需要處理

* 3、指標最後1bit始終為0,此處體現出nginx設計巧妙之處

*/ee.events = events | (uint32_t)flags;

ee.data.ptr = (void *)((uintptr_t)c | ev->instance);

ngx_log_debug3(ngx_log_debug_event, ev->log, 0,

"epoll add event: fd:%d op:%d ev:%08xd",

c->fd, op, ee.events);

if (epoll_ctl(ep, op, c->fd, &ee) == -1)

ev->active = 1; //必須把當前事件active設定為1 代表該事件已經註冊到epoll中

#if 0

ev->oneshot = (flags & ngx_oneshot_event) ? 1 : 0;

#endif

return ngx_ok;

}

這裡需要關注兩點:

2、當註冊完事件之後,必須把active設定為1。那麼什麼時候設定為0呢?把當前事件移除epoll時設定為0。

/**

* 從事件驅動epoll中刪除事件

* @param ev 待刪除事件物件

* @param event 事件型別

* 取值為 ngx_read_event ngx_write_event

* @param flags

*/static ngx_int_t

ngx_epoll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)

c = ev->data;

if (event == ngx_read_event)

else

if (e->active)

else

ngx_log_debug3(ngx_log_debug_event, ev->log, 0,

"epoll del event: fd:%d op:%d ev:%08xd",

c->fd, op, ee.events);

if (epoll_ctl(ep, op, c->fd, &ee) == -1)

ev->active = 0; //事件被移除 需要把active設定為0

return ngx_ok;

}

事件從epoll中刪除,**邏輯與新增流程打通小異,此處不再深入剖析。

通過分析nginx的epoll模型,對於epoll模型處理有了更加深入的了解,到現在為止,越來越發現nginx真的是一款非常優秀的軟體,值得我們深入分析。下面一篇介紹nginx驚群處理。

Nginx事件模組

這是事件模組都必須實現的介面。typedef struct ngx event module t typedef struct ngx event actions t typedef struct ngx event s ngx event t struct ngx event s 其中的最核心的是...

Nginx學習筆記之事件驅動框架處理流程

nginx對請求的處理是通過事件觸發的,模組作為事件消費者,只能被事件收集 分發器呼叫。在nginx中,接收到乙個請求時,不會產生乙個單獨的程序來處理該請求,而是由事件收集 分發器 程序 呼叫某個模組,由模組處理請求,處理完後再返回到事件收集 分發器 ngx event core module模組的...

初步學習jQuery之事件

在dom中提供了load事件用於頁面載入完畢之後執行機制,jquery提供了ready 方法實現相似的功能,但是存在以下的區別。1.dom中的load事件沒有任何的簡寫形式,但是在jquery的ready 方法中提供了簡寫形式。2.在html頁面載入完成以後,load事件才會被觸發 而在dom節點樹...