天天看點

3.6.進階IO

3.6.1.非阻塞IO

3.6.1.1、阻塞與非阻塞

3.6.1.2、為什麼有阻塞式

(1)常見的阻塞:wait、pause、sleep等函數;read或write某些檔案時

(2)阻塞式的好處:當條件沒有滿足時,先交出CPU,讓其他程序運作

3.6.1.3、非阻塞

(1)為什麼要實作非阻塞

由于阻塞式類似于棧,前面阻塞的程序沒有執行,後面阻塞的程序就無法執行

(2)如何實作非阻塞IO通路:

O_NONBLOCK: 隻能在打開的時候設定

fcntl: 可以在檔案打開後設定

3.6.2.阻塞式IO的困境

3.6.2.1、程式中讀取鍵盤

3.6.2.2、程式中讀取滑鼠

3.6.2.3、程式中同時讀取鍵盤和滑鼠

3.6.2.4、問題分析

3.6.3.并發式IO的解決方案

3.6.3.1、非阻塞式IO

3.6.3.2、多路複用IO

3.6.3.3、異步通知(異步IO)

非阻塞式:

優點:可以不用等待條件,不論條件滿不滿足,都執行後面的程式。可以通過while不斷檢查條件的發生,來達到同時(宏觀)運作多個非阻塞,例如(同時檢查滑鼠和鍵盤)

缺點:

1.如果我們想實作當條件發生時就立即響應這個功能,就得不斷檢查條件,太浪費CPU

2.如果while中有多個非阻塞,那麼當在執行某個非阻塞時,可能另一個非阻塞的條件已經發生,這樣就會導緻漏掉一些資訊

3.6.4.IO多路複用原理

3.6.4.1、何為IO多路複用

(1)IO multiplexing

(2)用在什麼地方?多路非阻塞式IO。

(3)select和poll

(4)外部表現為阻塞式,内部非阻塞式自動輪詢多路阻塞式IO

其實内部就是while加非阻塞(類似),但是它内部不會占用CPU 太多時間

3.6.4.2、select函數介紹

FD_ISSET(int fd, fd_set *set) 這個函數很有意思,當注冊完一個檔案後,再調用這個函數檢查這個檔案描述符,得到的值式非零,

當調用了select()後,再退出後,如果這個檔案描述符的阻塞沒有發生,則再調用這個函數就會傳回0,如果發生了就會傳回非0,

可以用于檢測阻塞有沒有發生

3.6.4.3、poll函數介紹

優點:不會浪費太多CPU時間,且達到while加非阻塞的效果

缺點:

1.select和poll本身時阻塞式的,當裡面的條件沒滿足或者逾時,就會一直阻塞,

2.這兩個函數可以同時注冊多個阻塞,但是隻要有一個阻塞發生就會馬上退出函數,而不會等其它阻塞發生,更不會等全部阻塞發生後才退出

3.6.5.IO多路複用實踐

3.6.5.1、用select函數實作同時讀取鍵盤滑鼠

3.6.5.2、用poll函數實作同時讀取鍵盤滑鼠

3.6.6.異步IO

3.6.6.1、何為異步IO

(1)幾乎可以認為:異步IO就是作業系統用軟體實作的一套中斷響應系統。

(2)異步IO的工作方法是:我們目前程序注冊一個異步IO事件(使用signal注冊一個信号SIGIO的處理函數),然後目前程序可以正常處理自己的事情,當異步事件發生後目前程序會收到一個SIGIO信号進而執行綁定的處理函數去處理這個異步事件。

類似中斷

3.6.6.2、涉及的函數:

(1)fcntl(F_GETFL、F_SETFL、O_ASYNC、F_SETOWN)

設定檔案的異步IO屬性

(2)signal或者sigaction(SIGIO)

注冊異步IO處理函數

3.6.3.代碼實踐

優點:

1.類似中斷處理,可以一直檢測,

2.當一個滑鼠阻塞發生,然後執行相應處理函數後,還可以繼續檢測滑鼠阻塞,而不用手動又來重新添加一個滑鼠阻塞,

缺點:還沒發現

展望:如何撤銷這個阻塞事件

3.6.7存儲映射IO

3.6.7.1、mmap函數

3.6.7.2、LCD顯示和IPC之共享記憶體

3.6.7.3、存儲映射IO的特點

(1)共享而不是複制,減少記憶體操作

(2)處理大檔案時效率高,小檔案不劃算

3.6.8多程序實作多個IO同時檢測

如父程序實作一個IO,子程序實作一個IO,就可簡單實作多個IO同時檢測

繼續閱讀