設定完需要監聽的事件之後,就開始event loop了。在libev中,該工作由ev_run函式完成。它的大致流程如下:
intev_run (ev_p_
intflags)
return
activecnt;
}
inline_size voidfd_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 structanpending;
回到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...