天天看點

nginx中的epoll模型

要了解epoll模型,就要一個一個知識點由淺至深地去探索。

1.IO複用技術

nginx中的epoll模型

IO流請求作業系統核心,有串行處理和并行處理兩種概念。

串行處理是前面一個操作處理地時候,後面的所有操作都需要等待。是以,必須考慮以并行處理的方式來完成整個IO流的請求,實作最大的并發和吞吐。這裡就用到了IO複用技術。

IO複用技術就是讓一個Socket來做複用完成整個IO流的請求。實作IO流的請求其中一種方式就是多線程,但是多線程會占用大量資源,不便于管理,是以又出現了IO多路複用技術。

2.IO多路複用技術

IO多路複用是指多個描述符的I/O操作都能在一個線程内并發交替地順序完成,這裡的複用指的是複用同一個線程。

對作業系統核心而言,多路複用其實是要完成作業系統IO的請求,對于IO檔案的請求,當一個IO流要進行對應的檔案處理的時候,要擷取一組檔案的描述符,當檔案描述符還沒就緒的時候,它就一直在等待,直到描述符就緒,就馬上上報系統的一個通知的機制,以此來告訴主應用程式它已經準備就緒了,你可以來操作了。這種方式就是IO多路複用方式。

3.IO多路複用技術的實作

IO多路複用技術的實作方式有select、poll和epoll,它們都是linux核心下的常見多路複用模型。

其中最早出現的是select模型。

4.select模型

多路複用其實就是核心态對IO請求的時候,會主動地發送所需要處理的檔案對象就緒時檔案的就緒資訊給應用端,應用端在FD(File Description)沒有就緒之前都是block,也就是阻塞對應的Socket請求,也會維護一個FD的清單。當核心态發送可用的資訊,FD就緒之後,應用端采用select這種模式,會一直在周遊所維護的FD檔案描述符的清單,以等到喚醒對應的線程完成對應的資料拷貝。select模型能夠監視檔案描述符的數量存在最大限制,且在整個過程中,select模型采用的是線性周遊的模式,這種模式效率低下。

nginx中的epoll模型

5.epoll模型

epoll模型優化和完善了select模式的缺點,每當FD就緒,采用系統的回調函數直接将FD放入,效率高,無監視檔案描述符的數量限制。 

6.epoll模型的原理

設想一個場景:有100萬使用者同時與一個程序保持着TCP連接配接,而每一時刻隻有幾十個或幾百個TCP連接配接是活躍的(接收到TCP包),也就是說,在每一時刻,程序隻需要處理這100萬個連接配接中的一小部分連接配接。那麼,如何才能高效地處理這種場景呢?程序是否在每次詢問作業系統收集有事件發生的TCP連接配接時,把這100萬個連接配接告訴作業系統,然後由作業系統找出其中有事件發生的幾百個連接配接呢?實際上,在Linux核心2.4版本之前,select或poll事件驅動模型就是這樣處理的。

這裡有個非常明顯的問題,即在某一時刻,程序收集有事件的連接配接時,其實這100萬連接配接中的大部分是沒有事件發生的。是以,如果每次收集事件時,都把這100萬連接配接的套接字傳給作業系統(這首先就是使用者态記憶體到核心态記憶體的大量複制),而由作業系統核心尋找這些連接配接上有沒有未處理的事件,将會是巨大的資源浪費,然而select和poll就是這樣做的,是以它們最多隻能處理幾千個并發連接配接。

而epoll就厲害了,它會在Linux核心中申請一個簡易的檔案系統,把原先的一個select或poll調用分成了3個部分:

1.調用epoll_create建立一個epoll對象(在epoll檔案系統中給這個句柄配置設定資源,一棵紅黑樹和一個準備就緒list連結清單)。

2.調用epoll_ctl向epoll對象中添加這100萬個連接配接的套接字。就是把socket放到紅黑樹上,給核心中斷處理程式注冊一個回調函數,然後告訴核心如果這個句柄的中斷到了,就把這個socket放到準備就緒list連結清單裡。

3.調用epoll_wait收集發生事件的TCP連接配接。到準備就緒list連結清單中處理socket,并把資料傳回給使用者。

你要去做一個大人,不要回頭,不要難過。

繼續閱讀