這篇文章主要介紹“Libuv事件循環(huán)實現(xiàn)的邏輯是什么”,在日常操作中,相信很多人在Libuv事件循環(huán)實現(xiàn)的邏輯是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Libuv事件循環(huán)實現(xiàn)的邏輯是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領域值得信任、有價值的長期合作伙伴,公司提供的服務項目有:申請域名、網(wǎng)站空間、營銷軟件、網(wǎng)站建設、朝陽縣網(wǎng)站維護、網(wǎng)站推廣。
Libuv是一個跨平臺的的基于事件驅(qū)動的異步io庫。但是他提供的功能不僅僅是io,包括進程、線程、信號、定時器、進程間通信等。
Libuv使用各平臺提供的事件驅(qū)動模塊實現(xiàn)異步(epoll, kqueue, IOCP, event
ports)。他用來支持上層非文件io的模塊。libuv把上層的事件和回調(diào)封裝成io觀察者(uv__io_t)放到底層的事件驅(qū)動模塊。當事件觸發(fā)的時候,libuv會執(zhí)行io觀察者中的回調(diào)。
Libuv實現(xiàn)一個線程池用來支持上層文件io、DNS以及用戶層耗cpu的任務。
Libuv的整體執(zhí)行架構(gòu)
從上圖中我們大致了解到,Libuv分為幾個階段,然后在一個循環(huán)里不斷執(zhí)行每個階段里的任務。下面我們具體看一下每個階段。
1 更新當前事件,在每次事件循環(huán)開始的時候,libuv會更新當前事件到變量中,這一輪循環(huán)的剩下操作可能使用這個變量獲取當前事件,避免過多的系統(tǒng)調(diào)用影響性能。
2 如果時間循環(huán)是處于alive狀態(tài),則開始處理事件循環(huán)的每個階段。否則退出這個事件循環(huán)。alive狀態(tài)是什么意思呢?如果有active和ref狀態(tài)的handle,active狀態(tài)的request或者closing狀態(tài)的handle則認為事件循環(huán)是alive的(具體實現(xiàn)后續(xù)會分析)。
3 timer階段:判斷最小堆中的節(jié)點哪個節(jié)點超時了,執(zhí)行他的回調(diào)。
4 pending階段:執(zhí)行pending回調(diào)。一般來說,所有的io回調(diào)(網(wǎng)絡,文件,dns)都會在poll io階段執(zhí)行。但是有的情況下,poll io階段的回調(diào)會延遲到下一次循環(huán)執(zhí)行,那么這種回調(diào)就是在pending階段執(zhí)行的。
5 idle階段:如果節(jié)點處理avtive狀態(tài),每次事件循環(huán)都會被執(zhí)行(idle不是說事件循環(huán)空閑的時候才執(zhí)行)。
6 prepare階段:和idle階段一樣。
8 poll io階段:調(diào)用各平臺提供的io多路復用接口,最多等待timeout時間。返回的時候,執(zhí)行對應的回調(diào)。(比如linux下就是epoll模式)
9 check階段:和idle prepare一樣。
10 closing階段:處理調(diào)用了uv_close函數(shù)的handle的回調(diào)。
11 如果libuv是以UV_RUN_ONCE模式運行的,那事件循環(huán)即將退出。但是有一種情況是,poll io階段的timeout的值是timer階段的節(jié)點的值。并且poll io階段是因為超時返回的,即沒有任何事件發(fā)生,也沒有執(zhí)行任何io回調(diào)。這時候需要在執(zhí)行一次timer階段。因為有節(jié)點超時了。
12 一輪事件循環(huán)結(jié)束,如果libuv以UV_RUN_NOWAIT 或 UV_RUN_ONCE模式運行的,則退出事件循環(huán)。如果是以UV_RUN_DEFAULT模式運行的并且狀態(tài)是alive,則開始下一輪循環(huán)。否則退出事件循環(huán)。
下面是Libuv事件循環(huán)實現(xiàn)的邏輯。
int uv_run(uv_loop_t* loop, uv_run_mode mode) {
int timeout;
int r;
int ran_pending;
// 在uv_run之前要先提交任務到loop
r = uv__loop_alive(loop);
// 事件循環(huán)沒有任務執(zhí)行,即將退出,設置一下當前循環(huán)的時間
if (!r)
uv__update_time(loop);
// 沒有任務需要處理或者調(diào)用了uv_stop
while (r != 0 && loop->stop_flag == 0) {
// 更新loop的time字段
uv__update_time(loop);
// 執(zhí)行超時回調(diào)
uv__run_timers(loop);
// 執(zhí)行pending回調(diào),ran_pending代表pending隊列是否為空,即沒有節(jié)點可以執(zhí)行
ran_pending = uv__run_pending(loop);
// 繼續(xù)執(zhí)行各種隊列
uv__run_idle(loop);
uv__run_prepare(loop);
timeout = 0;
// 執(zhí)行模式是UV_RUN_ONCE時,如果沒有pending節(jié)點,才會阻塞式poll io,默認模式也是
if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
timeout = uv_backend_timeout(loop);
// poll io timeout是epoll_wait的超時時間
uv__io_poll(loop, timeout);
uv__run_check(loop);
uv__run_closing_handles(loop);
// 還有一次執(zhí)行超時回調(diào)的機會,因為poll io階段可能是因為定時器超時返回的。
if (mode == UV_RUN_ONCE) {
uv__update_time(loop);
uv__run_timers(loop);
}
r = uv__loop_alive(loop);
// 只執(zhí)行一次,退出循環(huán),UV_RUN_NOWAIT表示在poll io階段不會阻塞并且循環(huán)只執(zhí)行一次
if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT)
break;
}
// 是因為調(diào)用了uv_stop退出的,重置flag
if (loop->stop_flag != 0)
loop->stop_flag = 0;
// 返回是否還有活躍的任務(handle或request),業(yè)務代表可以再次執(zhí)行uv_run
return r;
}
到此,關于“Libuv事件循環(huán)實現(xiàn)的邏輯是什么”的學習就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關知識,請繼續(xù)關注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
標題名稱:Libuv事件循環(huán)實現(xiàn)的邏輯是什么
本文網(wǎng)址:http://www.sd-ha.com/article42/iidjhc.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供App設計、響應式網(wǎng)站、、網(wǎng)站設計公司、虛擬主機、云服務器
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)