linux進程 阻塞和非阻塞操做

在咱們看全功能的 read 和 write 方法的實現以前, 咱們觸及的最後一點是決定什麼時候使 進程睡眠. 有時實現正確的 unix 語義要求一個操做不阻塞, 即使它不能徹底地進行下去.linux

 

有時還有調用進程通知你他不想阻塞, 無論它的 I/O 是否繼續. 明確的非阻塞 I/O 由 filp->f_flags 中的 O_NONBLOCK 標誌來指示. 這個標誌定義於 <linux/fcntl.h>, 被ide

<linux/fs.h>自動包含. 這個標誌得名自"打開-非阻塞", 由於它可在打開時指定(而且起函數

初只能在那裏指定). 若是你瀏覽源碼, 你會發現一些對一個 O_NDELAY 標誌的引用; 這 是一個替代 O_NONBLOCK 的名子, 爲兼容 System V 代碼而被接受的. 這個標誌缺省地被 清除, 由於一個等待數據的進程的正常行爲僅僅是睡眠. 在一個阻塞操做的狀況下, 這是 缺省地, 下列的行爲應當實現來符合標準語法:性能

 

  • · 若是一個進程調用 read 可是沒有數據可用(還沒有), 這個進程必須阻塞. 這個進程 在有數據達到時被馬上喚醒, 而且那個數據被返回給調用者, 即使小於在給方法的 count 參數中請求的數量.
  • · 若是一個進程調用 write 而且在緩衝中沒有空間, 這個進程必須阻塞, 而且它必 須在一個與用做 read 的不一樣的等待隊列中. 當一些數據被寫入硬件設備, 而且在

輸出緩衝中的空間變空閒, 這個進程被喚醒而且寫調用成功, 儘管數據可能只被部 分寫入若是在緩衝只沒有空間給被請求的 count 字節.unix

 

這 2 句都假定有輸入和輸出緩衝; 實際上, 幾乎每一個設備驅動都有. 要求有輸入緩衝是 爲了不丟失到達的數據, 當無人在讀時. 相反, 數據在寫時不能丟失, 由於若是系統調隊列

 

用不能接收數據字節, 它們保留在用戶空間緩衝. 即使如此, 輸出緩衝幾乎一直有用, 對 於從硬件擠出更多的性能.進程

 

在驅動中實現輸出緩衝所得到的性能來自減小了上下文切換和用戶級/內核級切換的次數. 沒有一個輸出緩衝(假定一個慢速設備), 每次系統調用接收這樣一個或幾個字符, 而且當 一個進程在 write 中睡眠, 另外一個進程運行(那是一次上下文切換). 當第一個進程被喚 醒, 它恢復(另外一次上下文切換), 寫返回(內核/用戶轉換), 而且這個進程從新發出系統 調用來寫入更多的數據(用戶/內核轉換); 這個調用阻塞而且循環繼續. 增長一個輸出緩 衝可容許驅動在每一個寫調用中接收大的數據塊, 性能上有相應的提升. 若是這個緩衝足夠 大, 寫調用在第一次嘗試就成功 -- 被緩衝的數據以後將被推到設備 -- 沒必要控制須要返 回用戶空間來第二次或者第三次寫調用. 選擇一個合適的值給輸出緩衝顯然是設備特定的.事件

 

咱們不使用一個輸入緩衝在 scull 中, 由於數據當發出 read 時已經可用. 相似的, 不用 輸出緩衝, 由於數據被簡單地拷貝到和設備關聯的內存區. 本質上, 這個設備是一個緩衝, 所以額外緩衝的實現多是多餘的. 咱們將在第 10 章見到緩衝的使用.內存

 

若是指定 O_NONBLOCK, read 和 write 的行爲是不一樣的. 在這個狀況下, 這個調用簡單 地返回 -EAGAIN(("try it agin")若是一個進程當沒有數據可用時調用 read , 或者若是 當緩衝中沒有空間時它調用 write .源碼

 

如你可能指望的, 非阻塞操做馬上返回, 容許這個應用程序輪詢數據. 應用程序當使用 stdio 函數處理非阻塞文件中, 必須當心, 由於它們容易搞錯一個的非阻塞返回爲 EOF. 它們始終必須檢查 errno.

 

天然地, O_NONBLOCK 也在 open 方法中有意義. 這個發生在當這個調用真正阻塞長時間 時; 例如, 當打開(爲讀存取)一個 沒有寫者的(尚無)FIFO, 或者存取一個磁盤文件使用 一個懸掛鎖. 經常地, 打開一個設備或者成功或者失敗, 沒有必要等待外部的事件. 有時, 可是, 打開這個設備須要一個長的初始化, 而且你可能選擇在你的 open 方法中支持 O_NONBLOCK , 經過馬上返回 -EAGAIN,若是這個標誌被設置. 在開始這個設備的初始化進 程以後. 這個驅動可能還實現一個阻塞 open 來支持存取策略, 經過相似於文件鎖的方式. 咱們將見到這樣一個實如今"阻塞 open 做爲對 EBUSY 的替代"一節, 在本章後面.

 

一些驅動可能還實現特別的語義給 O_NONBLOCK; 例如, 一個磁帶設備的 open 經常阻塞 直到插入一個磁帶. 若是這個磁帶驅動器使用 O_NONBLOCK 打開, 這個 open 馬上成功, 不論是否介質在或不在.

 

只有 read, write, 和 open 文件操做受到非阻塞標誌影響.

相關文章
相關標籤/搜索