什麼是IO多路複用?Nginx的處理機制

OldBoy~發表於2018-03-08

先來說一下什麼是IO複用?

IO複用解決的就是併發行的問題,比如多個使用者併發訪問一個WEB網站,對於服務端後臺而言就會產生多個請求,處理多個請求對於中介軟體就會產生多個IO流對於系統的讀寫。那麼對於IO流請求作業系統核心有並行處理和序列處理的概念,序列處理的方式是一個個處理,前面的發生阻塞,就沒辦法完成後面的請求。這個時候我們必須考慮並行的方式完成整個IO流的請求來實現最大的併發和吞吐,這時候就是用到IO複用技術。IO複用就是讓一個Socket來作為複用完成整個IO流的請求。當然實現整個IO流的請求多執行緒的方式就是其中一種。

***下面是一些舉例,讓你更清楚的瞭解什麼是IO多路複用***

舉例:在教室裡面有一個老師同時給學生出一道題目,檢查每個學生做的是否正確,這時候老師可以選擇一個一個學生的去問學生是否做完。如果A學生沒做完,那麼再問B學生,B學生沒做完再問C學生,挨個問下去,如果發現問道某一個學生,某一個學生說做完的時候,這時候再給當下學生解答。那麼這時候會發現,如果一個學生髮生了阻塞,阻塞在一個學生下,其他學生就會耽誤了,這時候對整個課堂效率就底下。這就是序列請求類處理。
那麼多執行緒呢?
再舉例:也是這個場景,給學生出題讓學生解答。這個老師學會了分身術,每個老師對每個學生進行監聽,看學生是否答題完並作出解答,這樣效率就高了。這就是多執行緒進行IO流處理,那麼多執行緒IO流就會產生一定的消耗,資源問題的存在。
什麼是IO多路複用呢?
再再舉例:同樣也是答題場景,其實就是改為了由學生來主動跟老師彙報,比如學生B答完了,這時候老師跟B進行解答,因為B學習效率高,其他學生還在做題,這時候給學生B解答完後,老師再給第二個學生解答,這時候學生主動彙報,效率就高了。這種方式就是IO多路複用的方式。特點:學生主動彙報。
對於作業系統而言,IO多路複用就是要完成作業系統IO的請求。對於IO檔案的請求,當一個IO流要進行檔案處理的時候,要獲取一組檔案的描述符,當檔案描述符還沒有就緒時,那麼它就在等待,直到描述符一旦就緒,馬上上報系統通知的機制,告訴應用程式我準備就緒,你可以來操作了。這就是IO多路複用的方式。
這種機制處理起來就很高效,多路複用就是在一個執行緒裡,交替併發的完成。複用的就是一個執行緒。

------------------------下面來看一下知乎帖子幾個前輩給出的比較粗俗易懂的解答------------------------

李遙:

你有N個不知道什麼時候來水的水龍頭需要接水,你根據某種訊號一會兒擰這個龍頭,一會兒擰那個龍頭把水都接了就是多路複用(一個執行緒)。使用殘像拳在每個水龍頭前派一個你的分身蹲守就是Threaded IO。其實後者也沒啥不好,因為未來的核心會消除上下文切換的軟硬體效能損耗。

Leslie:

要弄清問題先要知道問題的出現原因

原因:
由於程式的執行過程是線性的(也就是順序執行),當我們呼叫低速系統I/O(read,write,accept等等),程式可能阻塞,此時程式就阻塞在這個呼叫上,不能執行其他操作.阻塞很正常. 接下來考慮這麼一個問題: 一個伺服器程式和一個客戶端程式通訊,伺服器端read(sockfd1,bud,bufsize),此時客戶端程式沒有傳送資料,那麼read(阻塞呼叫)將阻塞直到客戶端呼叫write(sockfd,but,size) 發來資料. 在一個客戶和伺服器通訊時這沒什麼問題,當多個客戶與伺服器通訊時,若伺服器阻塞於其中一個客戶sockfd1,當另一個 客戶的資料到達套接字sockfd2時,伺服器不能處理,仍然阻塞在read(sockfd1,...)上;此時問題就出現了,不能及時處理另一個客戶的服務,咋麼辦?I/O多路複用來解決!
I/O多路複用:
繼續上面的問題,有多個客戶連線, sockfd1,sockfd2,sockfd3..sockfdn 同時監聽這n個客戶,當其中有一個發來訊息 時就從select的阻塞中返回,然後就呼叫read讀取收到訊息的sockfd,然後又迴圈回select 阻塞;這樣就不會因為阻塞在其中一個上而不能處理另一個客戶的訊息
Q:
那這樣子,在讀取socket1的資料時,如果其它socket有資料來,那麼也要等到socket1讀取完了才能繼續讀取其它socket的資料吧。那不是也阻塞住了嗎?而且讀取到的資料也要開啟執行緒處理吧,那這和多執行緒IO有什麼區別呢?
A:
1.CPU本來就是線性的不論什麼都需要順序處理並行只能是多核CPUhttp:
2.io多路複用本來就是用來解決對多個I/O監聽時,一個I/O阻塞影響其他I/O的問題,跟多執行緒沒關係.
3.跟多執行緒相比較,執行緒切換需要切換到核心進行執行緒切換,需要消耗時間和資源. 而I/O多路複用不需要切換線/程式,效率相對較高,特別是對高併發的應用nginx就是用I/O多路複用,故而效能極佳.但多執行緒程式設計邏輯和處理上比I/O多路複用簡單.而I/O多路複用處理起來較為複雜.

某匿名使用者:

這些名詞比較繞口,理解涵義就好。一個epoll場景:一個酒吧服務員(一個執行緒),前面趴了一群醉漢,突然一個吼一聲“倒酒”(事件),你小跑過去給他倒一杯,然後隨他去吧,突然又一個要倒酒,你又過去倒上,就這樣一個服務員服務好多人,有時沒人喝酒,服務員處於空閒狀態,可以乾點別的玩玩手機。至於epoll與select,poll的區別在於後兩者的場景中醉漢不說話,你要挨個問要不要酒,沒時間玩手機了。io多路複用大概就是指這幾個醉漢共用一個服務員。

某匿名使用者:

1 人贊同了該回答
IO模式一般分為同步IO和非同步IO. 同步IO會阻塞程式, 非同步IO不會阻塞程式. 目前linux上大部分用的是同步IO, 非同步IO在linux上目前還不成熟, 不過windows的iocp算是真正的非同步IO。
同步IO又分為阻塞IO, 非阻塞IO, IO多路複用. What? 同步IO明明會阻塞程式,為什麼也包括非阻塞IO? 因為非阻塞IO雖然在請求資料時不阻塞, 但真正資料來臨時,也就是核心資料拷貝到使用者資料時, 此時程式是阻塞的.
那麼這些IO模式的區別分別是什麼? 接下來舉個小例子來說明. 假設你現在去女生宿舍樓找自己的女神, 但是你只知道女神的手機號,並不知道女神的具體房間
先說同步IO的情況,
1. 阻塞IO, 給女神發一條簡訊, 說我來找你了, 然後就默默的一直等著女神下樓, 這個期間除了等待你不會做其他事情, 屬於備胎做法.
2. 非阻塞IO, 給女神發簡訊, 如果不回, 接著再發, 一直髮到女神下樓, 這個期間你除了發簡訊等待不會做其他事情, 屬於專一做法.
3. IO多路複用,是找一個宿管大媽來幫你監視下樓的女生, 這個期間你可以些其他的事情. 例如可以順便看看其他妹子,玩玩王者榮耀, 上個廁所等等。IO複用又包括 select, poll, epoll 模式. 那麼它們的區別是什麼?
3.1 select大媽每一個女生下樓, select大媽都不知道這個是不是你的女神, 她需要一個一個詢問, 並且select大媽能力還有限, 最多一次幫你監視1024個妹子
3.2 poll大媽不限制盯著女生的數量, 只要是經過宿舍樓門口的女生, 都會幫你去問是不是你女神
3.3 epoll大媽不限制盯著女生的數量, 並且也不需要一個一個去問. 那麼如何做呢? epoll大媽會為每個進宿舍樓的女生臉上貼上一個大字條,上面寫上女生自己的名字, 只要女生下樓了, epoll大媽就知道這個是不是你女神了, 然後大媽再通知你.
上面這些同步IO有一個共同點就是, 當女神走出宿舍門口的時候, 你已經站在宿舍門口等著女神的, 此時你屬於阻塞狀態
接下來是非同步IO的情況
你告訴女神我來了, 然後你就去王者榮耀了, 一直到女神下樓了, 發現找不見你了, 女神再給你打電話通知你, 說我下樓了, 你在哪呢? 這時候你才來到宿舍門口. 此時屬於逆襲做法。

 

總結:
有多個客戶連線,1、2、3、4、5、N同時監聽這M個客戶,當其中有一個發來訊息時就從阻塞中返回,然後就進行 請求處理,然後又迴圈回阻塞;這樣就不會因為阻塞在其中一個上而不能處理另一個客戶的訊息

 

具體帖子地址:https://www.zhihu.com/question/32163005

相關文章