在呼叫io函式時,如果需要等待io事件準備就緒才返回執行結果就是阻塞的io呼叫,如果呼叫io函式時,不需要io事件準備就緒就可以返回結果就是非阻塞。
在早期的網路伺服器中為了處理多個連線請求往往需要開闢多個執行緒,每個執行緒負責乙個連線的處理,但是多執行緒需要進行cpu的上下文切換。而上下文切換需要處理檔案控制代碼,這些操作是十分繁瑣的,所以多執行緒並不是很好的解決方案。
select執行流程:
select是乙個阻塞函式,當沒有資料時,會一直阻塞在select函式那一行。
當有資料時會將rset中對應的位置中有io準備就緒事件置為1。
select函式返回,不在阻塞。
遍歷檔案描述符陣列,和rset陣列對比判斷哪些有io就緒事件。
讀取資料進行處理。
select缺點:
bitmap預設大小為1024,雖然可以調整但是有限度。
rset每次迴圈都必須從頭開始,不可重複使用。
儘管將rset從使用者態拷貝到核心態,有核心判斷是否有資料,但是還是存在著拷貝的開銷。
當有資料是select就會返回,但是select函式並不知道那個檔案描述符中有資料了,後面還需要再次對檔案描述符陣列進行遍歷,效率較低。
poll執行流程:
將檔案描述符拷貝到核心態。
poll為阻塞方法,執行poll方法,如果有資料會將fd對應的revents置為pollin。
方法返回後迴圈遍歷查詢那個fd的revents被置為pollin。
將revents重新復位便於復用。
對被置的fd進行處理。
解決的問題:
解決了bitmap大小限制的問題。
解決了rset的復用問題。
epoll函式時非阻塞的!!!
epoll執行流程:
當有資料的時候,會把相應的描述符「置位」,但是epoll沒有revent標誌位,所以並不是真正的置位。這時候會把有事件的描述符放到隊首。
epoll會返回有事件的檔案描述符的個數。
根據個數讀取前n個描述符。
讀取資料進行處理。
解決的問題:
基本解決了select的問題。
Linux下磁碟的IO的各種機制
要說linux下的io過程,就要先說下linux的位址空間問題,首先,linux有一段虛擬記憶體,以32位x86系統為例,虛擬記憶體為2 32 即4g的記憶體空間,核心將這4g的空間分為兩個部分,高位的1g位元組 從虛位址0xc0000000到0xffffffff 供核心使用,稱為 核心空間 而較低...
linux中的目錄IO
涉及到的標頭檔案 include include 目錄io 檔案io opendir 只能開啟目錄 mkdir 建立目錄 open readdir 讀目錄 read rewinddir 調整位置指標 telldir seekdir rewind ftell fseek closedir 關閉目錄 c...
Redis中的IO多路復用機制
提起redis,我們經常會說其底層是乙個單執行緒模型,但這是不嚴謹的。redis單執行緒指的是網路請求模組使用了乙個執行緒,即乙個執行緒處理所有網路請求,其他模組該使用多執行緒,仍會使用了多個執行緒。既然是單執行緒模型,那麼cpu不是redis的瓶頸。redis的瓶頸最有可能是機器記憶體或者網路頻寬...