1. 程式人生 > >3.6.1.非阻塞IO

3.6.1.非阻塞IO

一起 因此 運行 文件描述符 方式 回收 性能 無法 需要

本節講解什麽是非阻塞IO,如何將文件描述符修改為非阻塞式

3.6.1.1、阻塞與非阻塞

(1)阻塞是指函數調用會被阻塞。本質是當前進程調用了函數,進入內核裏面去後,因為當前進程的執行條件不滿足,內核無法裏面完成操作,就掛起這個進程,去執行其他進程。默認使用阻塞IO
(2)非阻塞IO當條件不滿足時直接停止當前操作,退出程序(?)。或者非阻塞IO條件不滿足時會一直占用CPU資源
(3)結合程序狀態轉換圖一起理解

3.6.1.2、為什麽有阻塞式
(1)常見的阻塞:wait、pause、sleep等函數;read或write某些文件時
wait等待回收子進程:當子進程沒死,父進程就不能回收子進程,內核就阻塞住父進程,知道子進程死去稱為僵屍進程,這時內核就會發一個信號給父進程,父進程就會被喚醒,去回收子進程。

(2)阻塞式的好處
非常有利於OS的性能發揮。阻塞時不會占用CPU,CPU可以去執行其他。

3.6.1.3、非阻塞

(1)為什麽要實現非阻塞
(2)如何實現非阻塞IO訪問:O_NONBLOCK和fcntl

a -- 阻塞
阻塞操作是指在執行設備操作時,若不能獲得資源,則掛起進程知道滿足可操作的條件後再進行操作;被掛起的進程進入休眠狀態(放棄CPU),被從調度器的運行隊列移走,直到等待的條件被滿足;
b -- 非阻塞
非阻塞的進程在不能進行設備操作時,並不掛起(繼續占用CPU),它或者放棄,或者不停地查詢,直到可以操作為止;
二者的區別可以看應用程序的調用是否立即返回!

  驅動程序通常需要提供這樣的能力:當應用程序進行 read()、write() 等系統調用時,若設備的資源不能獲取,而用戶又希望以阻塞的方式訪問設備,驅動程序應在設備驅動的xxx_read()、xxx_write() 等操作中將進程阻塞直到資源可以獲取,此後,應用程序的 read()、write() 才返回,整個過程仍然進行了正確的設備 訪問,用戶並沒感知到;若用戶以非阻塞的方式訪問設備文件,則當設備資源不可獲取時,設備驅動的 xxx_read()、xxx_write() 等操作立刻返回, read()、write() 等系統調用也隨即被返回。
  因為阻塞的進程會進入休眠狀態,因此,必須確保有一個地方能夠喚醒休眠的進程,否則,進程就真的掛了。喚醒進程的地方最大可能發生在中斷裏面,因為硬件資源獲得的同時往往伴隨著一個中斷。

  阻塞I/O通常由等待隊列來實現,而非阻塞I/O由輪詢來實現。

3.6.1.非阻塞IO