日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

libev源码解析——I/O模型

發(fā)布時(shí)間:2023/11/27 生活经验 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 libev源码解析——I/O模型 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

? ? ? ? 在《libev源碼解析——總覽》一文中,我們介紹過,libev是一個(gè)基于事件的循環(huán)庫(kù)。本文將介紹其和事件及循環(huán)之間的關(guān)系。(轉(zhuǎn)載請(qǐng)指明出于breaksoftware的csdn博客)

? ? ? ? 目前ibev支持如下IO事件模型:

  • select模型。對(duì)應(yīng)文件是ev_select.c。
  • poll模型。對(duì)應(yīng)文件是ev_poll.c。
  • epoll模型。對(duì)應(yīng)的文件是ev_epoll.c。
  • port模型。對(duì)應(yīng)文件是ev_port.c。
  • kqueue模型。對(duì)應(yīng)的文件是ev_kqueue.c。
  • iocp模型。即IO完成端口模型(I/O Completion Port)。

? ? ? ? 這些模型并不是我們這個(gè)系列介紹的重點(diǎn)。如果想了解select、poll、epoll模型,可以參閱《樸素、Select、Poll和Epoll網(wǎng)絡(luò)編程模型實(shí)現(xiàn)和分析》系列博文。(下圖是select模型的調(diào)用邏輯圖)

? ? ? ??

? ? ? ? 此處我們只要知道它們是libev可選的事件模型即可。至于選擇什么模型。要視loop_init的入?yún)lags。

static void noinline ecb_cold
loop_init (EV_P_ unsigned int flags) EV_THROW
{
……
#if EV_USE_IOCPif (!backend && (flags & EVBACKEND_IOCP  )) backend = iocp_init   (EV_A_ flags);
#endif
#if EV_USE_PORTif (!backend && (flags & EVBACKEND_PORT  )) backend = port_init   (EV_A_ flags);
#endif
#if EV_USE_KQUEUEif (!backend && (flags & EVBACKEND_KQUEUE)) backend = kqueue_init (EV_A_ flags);
#endif
#if EV_USE_EPOLLif (!backend && (flags & EVBACKEND_EPOLL )) backend = epoll_init  (EV_A_ flags);
#endif
#if EV_USE_POLLif (!backend && (flags & EVBACKEND_POLL  )) backend = poll_init   (EV_A_ flags);
#endif
#if EV_USE_SELECTif (!backend && (flags & EVBACKEND_SELECT)) backend = select_init (EV_A_ flags);
#endif
……
}

? ? ? ? backend是一個(gè)用于記錄libev使用的是哪種IO模型的標(biāo)記位。

? ? ? ? 在每個(gè)模型初始化函數(shù)中,都需要指定兩個(gè)模型相關(guān)的函數(shù)指針。比如epoll模型的初始化函數(shù)epoll_init中

int inline_size
epoll_init (EV_P_ int flags)
{
……backend_mintime = 1e-3; /* epoll does sometimes return early, this is just to avoid the worst */backend_modify  = epoll_modify;backend_poll    = epoll_poll;
……
}

? ? ? ? 而在select模型中則是

int inline_size
select_init (EV_P_ int flags)
{backend_mintime = 1e-6;backend_modify  = select_modify;backend_poll    = select_poll;
……
}

? ? ? ? backend_mintime是需要等待事件的超時(shí)秒數(shù);backend_modify是輪詢中修改事件信息的函數(shù)。backend_poll則是等待事件的函數(shù)。libev通過上述四個(gè)變量,隔離了不同模型選擇導(dǎo)致不同函數(shù)調(diào)用的問題。

? ? ? ? 但是這兒需要指出的是,libev并沒有將這種隔離做徹底。因?yàn)樵陉P(guān)閉IO模型時(shí),它仍然依靠backend的值,調(diào)用了不同函數(shù)(ev_loop_destroy中)

#if EV_USE_IOCPif (backend == EVBACKEND_IOCP  ) iocp_destroy   (EV_A);
#endif
#if EV_USE_PORTif (backend == EVBACKEND_PORT  ) port_destroy   (EV_A);
#endif
#if EV_USE_KQUEUEif (backend == EVBACKEND_KQUEUE) kqueue_destroy (EV_A);
#endif
#if EV_USE_EPOLLif (backend == EVBACKEND_EPOLL ) epoll_destroy  (EV_A);
#endif
#if EV_USE_POLLif (backend == EVBACKEND_POLL  ) poll_destroy   (EV_A);
#endif
#if EV_USE_SELECTif (backend == EVBACKEND_SELECT) select_destroy (EV_A);
#endif

? ? ? ? 個(gè)人認(rèn)為,可以在各個(gè)模型的初始化中,將其對(duì)應(yīng)的銷毀函數(shù)指針賦值給一個(gè)叫backend_destory的變量。這樣上述代表就可以變成一行了。

? ? ? ? 結(jié)合《libev源碼解析——調(diào)度策略》的內(nèi)容,我們可以用下圖表達(dá)出libev運(yùn)轉(zhuǎn)的大體流程。

? ? ? ? 針對(duì)上圖,可能有人會(huì)問:為什么backend_poll函數(shù)需要指定超時(shí)?我們讓其一直等待到有事件發(fā)生不是更好么?

? ? ? ? 還有人會(huì)問:“符合條件的監(jiān)視器”是否可以表述為“本次觸發(fā)事件對(duì)應(yīng)的監(jiān)視器”?

? ? ? ? 對(duì)于這些問題,我們將在之后章節(jié)給出答案。

總結(jié)

以上是生活随笔為你收集整理的libev源码解析——I/O模型的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。