什麼是io?
i/o是input/output的縮寫,即輸入輸出埠。每個裝置都會有乙個專用的i/o位址,使用者來處理自己的輸入輸出資訊。在linux中,一切皆檔案,檔案就是一串二進位製流而已,不管是socket,還是fifo,管道,終端都是檔案,都是流,在資訊交換的的過程中,我們都是對這些流進行資料的收發操作,簡稱i/o操作
i/o操作具體分為倆部分
等待資料就緒,也就是檔案描述符上由事件就緒我們才可以對其進行io操作
資料搬遷,說白了就是將乙個檔案中的資料搬到另乙個檔案中
五種i/o模型
阻塞i/o:在核心將資料準備好之前,系統呼叫會一直等待(所有的套接字,預設都是阻塞方式)
非阻塞式i/o:如果核心還未將資料準備好,系統呼叫仍會直接返回,並且返回ewouldblock錯誤碼
非阻塞io往往需要程式設計師以迴圈的方式反覆嘗試獨寫檔案描述符,這個過程叫輪詢,這對cpu來說是較大的浪費,一般只有特定場景下才使用
訊號驅動i/o:核心將資料準備好的時候,使用sigio訊號通知應用程式進行io操作
優點:無需等待;系統通知後去處理;**簡單;無需輪詢
缺點:處理讀資料時處於阻塞狀態;
i/o復用(i/o多路轉接):核心在於i/o多路轉接可以同時等待多個檔案描述符的就緒狀態
(用乙個執行緒等待多個檔案描述符)
非同步i/o:由核心在資料拷貝完成時,通知應用程式(而訊號驅動是告訴應用程式合適可以開始拷貝資料)
注:收到通知後,不一定會去處理
任何i/o過程中都包含倆個步驟:一是等待資料,二是將資料從核心拷貝到使用者空間,而且在實際應用中等待消耗的時間往往都遠遠高於拷貝讓i/o高效,最核心的方法就是讓等待時間盡量少
同步通訊於非同步通訊
這裡的同步,與同步和互斥中的同步不一樣
執行緒/程序間的同步互斥:
i/o多路轉接之select:
系統提供select函式來實現多路復用輸入輸出模型
select函式原型:
#includeint select(int nfds,fd_set *readfds,fd_set *writefds,fd_set *exceptfds,struct timeval *timeout);
引數解釋:
引數timeout的取值:
fd_set結構:
void fd_clr(int fd,fd_set *set); //用來清除描述片語set中相關fd的位
int fd_isset(int fd,fd_set *set); //用來測試描述片語set中相關的fd的位是否為真
void fd_set(int fd, fd_set *set); //用來設定描述片語set中相關的fd位
void fd_zero(fd_set *set); //用來清除描述片語set中的全部位
這個結構其實就是乙個整數陣列,更嚴格的說,是乙個「位圖」,使用點陣圖中對應的位來表示要監視的檔案描述符
函式返回值:
理解select執行過程:
理解select模型的關鍵在於理解fd_set,為了說明方便,去fd_set長度為1位元組,fd_set中的每一位代表乙個檔案描述符,則乙個位元組長的fd_set最大可以代表8個fd
select讀就緒:
select的優點:
select的缺點:
Linux的三種I O復用方式 select
select poll epollselect的原型是 int select int maxfd,fd set readfds,fd set,fd set writefds,fd set exceptfds,struct timeval timeout maxfd 監聽的最大檔案描述符的值 1 輪詢...
五種I O 模式
1.阻塞i o 模式是最普遍使用的i o 模式。大部分程式使用的都是阻塞模式的i o 缺 省的,乙個套接字建立後所處於的模式就是阻塞i o 模式。對於乙個udp 套接字來說,資料就緒的標誌比較簡單 l 已經收到了一整個資料報 l 沒有收到。而tcp 這個概念就比較複雜,需要附加一些其他的變數。在圖6...
五種IO模型
再講io模型之前,給大家舉乙個釣魚的例子。張三去釣魚,他釣魚的時候一動不動,一直看著魚竿,看有沒有動,無論是誰叫他,他都不動,只有等魚梢動了 魚上鉤了 他才會動 李四去釣魚,他沒有像張三那樣瓷楞著,只是時不時的輪詢檢查魚竿有沒有動。一直在動。王五也來釣魚,他就比較聰明了,在魚竿上掛個鈴鐺,只要鈴鐺響...