epoll模型

前言

最近一段時間看epoll的源碼,看的抓耳撓腮。本著分享的原則,分享一下我對epoll的理解,注意:本文并不能讓你從零開始學(xué)epoll,而是希望在你看epoll源碼也學(xué)的抓耳撓腮的時候,看到本文能對你有一丟小小的幫助。

epoll的整個流程

本篇文章并不會設(shè)計到具體源碼,只是涉及到epoll的數(shù)據(jù)交互的流程。

epoll_create

一個應(yīng)用程序,想要使用epoll模型,首先會創(chuàng)建一個epoll模型。epoll_create是在內(nèi)核創(chuàng)建一個epoll模型,你可以把這個模型想象做一個java對象。這個對象里有一個阻塞列表,一個就緒列表,一個紅黑樹。

epoll_ctl

每一次通訊,客戶端都會建立一個socket,socket有一個文件描述符fd,系統(tǒng)通過這個fd去操作socket,系統(tǒng)會封裝一個epitem(紅黑樹的節(jié)點),這個epitem包含socket和一個回調(diào)事件(當(dāng)然還有其他屬性,我們暫且不提)。然后內(nèi)核會把這個epitem添加到紅黑樹,當(dāng)然,也可以修改和刪除事件。

epoll_wait

用戶進程去就緒列表拿就緒事件。拿到就返回,拿不到就進入epoll阻塞列表,當(dāng)然也可以設(shè)置超時參數(shù)為0表示拿不到也立即返回。

回調(diào)事件

回調(diào)事件會根據(jù)監(jiān)聽的事件類型,把fd放到就緒列表。然后去通知阻塞進程。阻塞進程從就緒列表拿走就緒事件,也就是把就緒事件從內(nèi)核空間拷貝到用戶空間。

這是我對epoll模型的大概描述,接下來,從交互的層面再說一說:

網(wǎng)絡(luò)的一個數(shù)據(jù)包,是怎么找到具體的對應(yīng)的socket的回調(diào)事件的。

當(dāng)一個數(shù)據(jù)包從網(wǎng)絡(luò)傳輸過來,包含了協(xié)議,發(fā)送端ip 和端口,目標(biāo)端ip和接口(這也是socket的五大元素)。內(nèi)核根據(jù)這五個要素去找到對應(yīng)的socket,就可以拿到對應(yīng)的fd,有了fd,就可以去紅黑樹里找epitem,找到了epitem就可以去觸發(fā)回調(diào)事件?;卣{(diào)事件就可以把就緒事件放到就緒列表。
輸入netstat命名就可以查看系統(tǒng)的所有活躍的socket鏈接:


image.png

例子里,本地機器有兩個socket鏈接和172.217.27.42.443端口建立了鏈接,當(dāng)網(wǎng)絡(luò)數(shù)據(jù)包傳輸過來,發(fā)送端ip和端口號就是172.217.27.42.443,接收端可能是54040和54035端口,用發(fā)送端ip和端口號為參數(shù)去對應(yīng)foreign address,用接收端參數(shù)去對應(yīng)local address,就可以找到具體的哪一個socket連接。

備用鏈表

如果在拷貝就緒事件的時候,出現(xiàn)了新的就緒事件怎么辦,其實還有一個備用鏈表,拷貝事件的時候,如果有就緒事件產(chǎn)生,先放到備用鏈表,拷貝完成再把備用鏈表的就緒事件放到就緒列表里。

和select/ poll模型比較

epoll模型肯定是比select或者poll模型更復(fù)雜了??梢园裡poll類比于重型挖掘機,select或者poll就是輕型挖機,各有各的用途,重活面前,epoll肯定好用。但是活少而清的時候,select/poll模型反而更有優(yōu)勢。

如果想看細節(jié),還是得自己擼源碼,別人講只能聽個大概。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容