嵌入式Linux基本教程中,Linux有名管道的堵塞是一個令人困擾的問題,下面我們就來講一下這個問題是如何產生的,以更好地掌握其內部的邏輯關系。
一、問題由來
在先前操作有名管道相關試驗時,發現有名管道中存在有堵塞的問題,該堵塞是在調用open函數打開有名管道文件時發生,具體表現形式如下:
情況一:
有兩份代碼jack和rose,其通過編譯運行實現兩個進程之間的通信,兩份代碼均為調用open函數打開有名管道文件,其中jack作為數據讀取進程,用于讀取rose發送過來的數據,且jack中open的有名管道打開方式是以只讀方式打開,rose中的open有名管道的打開方式是以只寫方式打開,部分代碼書寫如下:
Jack部分
Rose部分
嵌入式Linux基本教程在Linux中如只先運行其中的某個程序時,不能得到打印信息,但兩個程序都執行后,Linux終端上得到兩端的提示信息打印。如圖1、2
圖1 只有一端執行時表現形式
情況二:
兩份代碼jack和rose,調用open函數打開有名管道時,如的打開的方式為可讀可寫方式(O_RDWR),則open函數再會堵塞,提示信息直接打印。部分代碼如下
Jack部分代碼
Rose部分代碼
圖示如圖2
情況總結:
調用 open()打開有名管道的進程open函數處可能會被阻塞。但如果同時以讀寫方式 (O_RDWR)打開,則一定不會導致阻塞;如果以只讀方式 ( O_RDONLY ) 打開,則調用 open() 函數的進程將會被阻塞直到有寫方打開管道;同樣以寫方式 ( O_WRONLY ) 打開也會阻塞直到有讀方打開管道。
二、問題原因
在用open打開FIFO時有可能會阻塞,原因就是當前只有讀端或寫端存在。換句話說,如果程序在打開FIFO時指定了只讀方式/只寫方式,那么該進程對于打開的FIFO來說就是一個讀端/寫端。如果指定的是讀寫方式,那么進程即是讀端又是寫端。嵌入式Linux基本教程表示這就好比如是一根水管,當水管的兩端都打開時,水管才能通水,反之只要有一端不同,水管就會堵塞。
三、有名管道讀寫數據問題
從FIFO中讀數據時(用read函數),如果沒有數據,默認是阻塞等待,直到有數據被寫入FIFO。如果read函數返回0,說明該FIFO所有的寫端都已關閉,程序要做相應的處理。向FIFO寫入數據時(使用write函數),如果FIFO有足夠空間,write函數會返回寫入的字節數;如果空間不夠,write函數會阻塞,直到寫完為止。當所有的讀端都關閉時,再向FIFO寫數據會出錯。內核會向寫進程發管道斷裂的信號(SIGPIPE), 從而終止該進程。
有關嵌入式Linux基本教程中Linux有名管道的堵塞問題就先說到這里,如果感興趣的話,可以到粵嵌系統培訓相關的知識。