epoll的原理和用法

2022-07-13 08:09:09 字數 1705 閱讀 6290

設想乙個場景,有100

萬使用者同時與乙個程序保持著

tcp連線,而每一時刻只有幾十個或幾百個tcp連線是活躍的(接收到tcp

包)也就是說,在每一時刻程序只需要處理這

100萬連線中的一小部分連線,那麼,如何才能高效的處理這種場景那,程序是否在每次詢問作業系統收集有事件發生的tcp

連線時,把這

100萬個連線告訴作業系統,然後由作業系統找出其中有事件發生的幾百個連線呢?,實際上在linux2.4

版本以前,那時的

select

或者poll

事件驅動方式就是這樣做的(就是每次通過輪詢的方式從

100萬個連線中找出活躍連線)

這裡有個明顯的問題,即在某一時刻,程序收集有事件的連線時,其實這100

萬連線中的大部分都是沒有事件發生的,因此,如果每次收集事件時,都把這100

萬連線的套接字傳給作業系統,而由作業系統核心尋找這些連線上有沒有未處理的事件,將會是巨大的資源浪費,而select

和poll

就是這樣做的,因此他們最多只能處理幾千個併發連線,而epoll

不是這樣做的,

epoll

把原先的乙個

select

或者poll

呼叫分成了

3個部分,呼叫

epoll_create

建立乙個

epoll

物件,呼叫

epoll_ctl

向epoll

物件中新增這

100萬個連線的套接字,呼叫epoll_wait

收集發生事件的連線,這樣只需要在程序啟動時建立乙個epoll

物件,並在需要的時候向他刪除或新增連線就可以了,在實際收集事件中,epoll_wait

的效率會非常高,因為呼叫

epoll_wait

時並沒有向它傳遞這

100萬個連線,核心也不需要去遍歷全部的連線

epoll_create方法

當某一程序呼叫epoll_create

方法時,

linux

核心會建立乙個

eventpoll

結構體,這個結構體中有兩個成員與

epoll

struct eventpoll

所有新增到

epoll

中的事件,都會與裝置(網絡卡)驅動程式建立**關係,也就是說相應的事件發生時會呼叫這裡的**方法,這個**方法在核心中叫做

ep_poll_callback

,當被呼叫時會把事件放到

rdllist

雙向鍊錶中(正是這種**機制使不用輪詢就可以知道哪些連線有事件發生)

當呼叫epoll_wait

檢查是否有發生事件的連線時,只是檢查

eventpoll

物件中的

rdllist

雙向鍊錶是否有

epitem

元素而已,如果

rdllist

鍊錶不為空,則把這裡的事件複製到使用者態記憶體中,同時將事件數量返回給使用者,因此

epoll_wait

的效率非常高。

epoll_ctl在向

epoll

物件中新增,修改和刪除事件時,從

rbr紅黑樹中查詢事件也非常的快,也就是說

epoll

是非常高效的,可以輕易處理百萬的併發。

epoll 和 kqueue 的原理

源引 首先我們來定義流的概念,乙個流可以是檔案,socket,pipe等等可以進行i o操作的核心物件。不管是檔案,還是套接字,還是管道,我們都可以把他們看作流。之後我們來討論i o的操作,通過read,我們可以從流中讀入資料 通過write,我們可以往流寫入資料。現在假定乙個情形,我們需要從流中讀...

epoll用法詳解

epoll i o event notification facility 在linux的網路程式設計中,很長的時間都在使用select來做事件觸發。在linux新的核心中,有了一種替換它的機制,就是epoll。相比於select,epoll最大的好處在於它不會隨著監聽fd數目的增長而降低效率。因為...

epoll原理剖析

首先我們來定義流的概念,乙個流可以是檔案,socket,pipe等等可以進行i o操作的核心物件。不管是檔案,還是套接字,還是管道,我們都可以把他們看作流。之後我們來討論i o的操作,通過read,我們可以從流中讀入資料 通過write,我們可以往流寫入資料。現在假定乙個情形,我們需要從流中讀資料,...