epoll,IO事件通知機制

2021-06-11 02:12:24 字數 2397 閱讀 3789

epoll 是poll的變種,它可以用來監視大批量的檔案描述符集,同時提供兩種觸發介面方式:邊緣觸發(edge-triggered)和水平觸發(level-trigered),通過使用以下的系統呼叫來建立和管理epoll例項。

#include

int epoll_create(int size);

int epoll_create1(int flags);

乙個epoll例項可以通過epoll_create()或epoll_create1()函式來建立,這兩個函式返回epoll物件的檔案描述符,引數size用來告訴核心需要分配的支援事件儲存空間,但不需要告訴核心最大的分配儲存數目,自從核心2.6.8開始, size引數沒有使用意義,但需要是乙個大於0的值。

epoll_create1()拓展了epoll_create()的功能,這個函式是最近核心(2.6.27)新加入的。flags可以是epoll_cloexec值。

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

epoll_ctl系統呼叫用來對epfd epoll例項進行操作。op操作型別值包括:

epoll_ctl_add,註冊目標檔案描述符fd到epfd epoll 例項, event是fd相關聯的事件;

epoll_ctl_mod,修改目標檔案描述符fd的event值;

epoll_ctl_del,從epfd裡刪除fd, event設定為null;

epoll_event結構體定義如下:

typedef union epoll_data epoll_data_t;

struct epoll_event ;

events成員是一系列事件型別「與」操作的值,事件型別包括:

epollin, 關聯的檔案可讀;

epollout,關聯的檔案可寫;

epollrdhup,流socket端關閉連線;

epollpri,緊急資料(urgent data)可讀;

epollerr,關聯檔案錯誤發生;

epollhup,關聯檔案結束;

epollet,使用邊緣觸發;

epolllt,使用水平觸發;

epoll_ctl呼叫成功返回0,失敗返回-1,並且設定errno。

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

當epfd epoll例項設定好後,呼叫epoll_wait函式進入監視階段,events用來存放滿足的時間。

邊緣觸發(edge-triggered,epollet)和水平觸發(level-triggered,epolllt)是epoll支援的兩種觸發方式。假如epoll監聽的檔案描述符接收到2k的資料,epoll_wait會返回,並儲存事件到events陣列中,接著程式使用read系統呼叫從fd中讀取1k資料,則在fd的快取buffer中還剩下1k的資料未讀,這個時候使用lt關聯的檔案會再次告訴epoll有資料可讀,而使用et方式關聯的則不會再次通知。

在通常的使用中et觸發模式常常跟nonblocking檔案描述符關聯,建議使用et模式的程式使用以下流程:

1、於非阻塞方式開啟檔案描述符;

2、呼叫read或者write函式知道它們返回eagain錯誤。

example:

#define max_events 10

struct epoll_event ev, events[max_events];

int listen_sock, conn_sock, nfds, epollfd;

/* set up listening socket, 'listen_sock' (socket(),

bind(), listen()) */

epollfd = epoll_create(10);

if (epollfd == -1)

ev.events = epollin;

ev.data.fd = listen_sock;

if (epoll_ctl(epollfd, epoll_ctl_add, listen_sock, &ev) == -1)

for (;;)

for (n = 0; n < nfds; ++n)

setnonblocking(conn_sock);

ev.events = epollin | epollet;

ev.data.fd = conn_sock;

if (epoll_ctl(epollfd, epoll_ctl_add, conn_sock,

&ev) == -1)

} else

}

do_use_fd()函式反覆的read操作,直到返回eagain後退出該函式。

等待 通知機制

waitnotify模式的注意事項 經典案例生產者消費者模式實現 實戰等待通知之交叉備份 舉例說明,廚師和服務員之間的互動 1.廚師做完一道菜的時間不確定,所以廚師將菜品放到 菜品傳遞臺 上的時間也不確定 2.服務員取到菜的時間取決於廚師,所以服務員就處於等待狀態 3.服務員如何取到菜呢?又得取決於...

Supervisor事件通知

supervisor事件通知,支援郵件,slack,webhook supervisor是 nix環境下的程序管理工具,可以把前台程序轉換為守護程序,當程序異常退出時自動重啟.supervisor event listener監聽程序異常退出事件,並傳送通知.supervisor event lis...

13 事件通知

dubbo提供了oninvoke onreturn onthrow3個事件 oninvoke 呼叫之前執行,如果被呼叫的服務有引數,那麼oninvoke也必要有和被呼叫服務一樣的引數 onreturn 呼叫之後執行,至少有乙個入參,第乙個入參是返回值,其餘是呼叫服務的引數 onthrow 丟擲異常後...