Libev學習筆記3

2022-02-13 03:23:05 字數 1489 閱讀 7500

設定完需要監聽的事件之後,就開始event loop了。在libev中,該工作由ev_run函式完成。它的大致流程如下:

int

ev_run (ev_p_

intflags)

return

activecnt;

}

inline_size void

fd_reify (ev_p)

if (o_reify &ev__iofdset)

backend_modify (ev_a_ fd, o_events, anfd->events); /*

epoll_modify */}

fdchangecnt = 0; /*

fdchanges陣列清空

*/}

前面說過,乙個fd對應乙個anfd,乙個anfd可能包含多個watcher,上面函式就是遍歷fdchanges陣列,將陣列中每個fd對應的所有watcher所關注的事件全部新增到事件驅動中,backend_modify巨集內部最終會呼叫事件驅動機制對應的修改函式,例如epoll的epoll_modify函式。

回到ev_run函式,接下來呼叫backend_poll函式,這個函式最終會呼叫事件驅動機制,阻塞等待事件的發生。當監控的事件發生時,libev提取這些事件,將它們放入乙個pendings陣列中,這個陣列儲存所有發生了但未處理的事件,放入過程如下:

/*

待執行的事件放入pendings陣列中

*/void

noinline

ev_feed_event (ev_p_

void *w, int

revents) ev_throw

pendingpri = numpri - 1

;}

pendings是個二維陣列,第一維是watcher的優先順序,第二維是同等優先順序的watcher的不同下標。pendings中的元素型別為anpending,定義如下:

typedef struct

anpending;

回到ev_run函式。這時,事件驅動機制檢測到有事件發生後返回,並將事件對應的watcher儲存在了pendings陣列中。接下來就要執行事件對應的**函式,也就是對「消費」該事件,ev_invoke_pending巨集負責該動作。ev_invoke_pending巨集最終會呼叫ev_invoke_pending函式,該函式定義如下:

/*

遍歷pendings二維陣列,執行事件觸發**函式

*/void

noinline

ev_invoke_pending (ev_p)

}}

外層while迴圈是按優先順序遞減,內層while迴圈同一優先順序的anpending按陣列順序進行遍歷,遍歷到的每乙個anpending都對應乙個watcher,得到watcher之後就執行該watcher對應的**函式。

至此,event loop完成一輪迴圈。

Libev學習筆記4

這一節首先分析libev的定時器部分,然後分析signal部分。對定時器的使用主要有兩個函式 ev timer init timeout watcher,timeout cb,5.5,0 ev timer start loop,timeout watcher 和ev io型別的watcher類似,t...

學習筆記3

第四單元 了解linux檔案系統 1.絕對路徑和相對路徑 a.絕對路徑 無論在系統的任何位置,從系統的頂級目錄 根目錄 一級一級往下排的表示方法 b.相對路徑 如果已經在某乙個目錄下面操作,那麼可以省略從根目錄到當前目錄的表示,若要切到該目錄下的任意位置,直接表示 2.系統中根目錄下子目錄的作用 a...

學習筆記3

乙個簡單的程式 import tensorflow as tf 定義網路結構和前向傳播演算法 def get weight shape w tf.variable return w def get bias shape b tf.variable return b def forward x,sha...