關於pipe管道的讀寫端關閉問題

2022-03-26 23:11:35 字數 1888 閱讀 3250

通過pipe在核心中建立乙個檔案,然後可以實現兩個程序通訊

管道是一種最基本的ipc機制,由 pipe 函式建立:

1 #include 2

int pipe(int filedes[2]);

呼叫 pipe 函式時在核心中開闢一塊緩衝區(稱為管道)用於通訊,它有乙個讀端乙個寫端,然後通過 filedes 引數傳出給使用者程式兩個檔案描述符,

filedes[0] 指向管道的讀端, filedes[1] 指向管道的寫端(很好記,就像0是標準輸入1是標準輸出一樣)。所以管道在使用者程式看起來就像乙個開啟的檔案,

通過 read(filedes[0]); 或者 write(filedes[1]); 向這個檔案讀寫資料其實是在讀寫核心緩衝區。 pipe 函式呼叫成功返回0,呼叫失敗返回-1。

開闢了管道之後如何實現兩個程序間的通訊呢?比如可以按下面的步驟通訊。

1. 父程序呼叫 pipe 開闢管道,得到兩個檔案描述符指向管道的兩端。

2. 父程序呼叫 fork 建立子程序,那麼子程序也有兩個檔案描述符指向同一管道。

3. 父程序關閉管道讀端,子程序關閉管道寫端。父程序可以往管道裡寫,子程序可以從管道裡讀,

管道是用環形佇列實現的,資料從寫端流入從讀端流出,這樣就實現了程序間通訊。

父程序只用到寫端,因而把讀端關閉,子程序只用到讀端,因而把寫端關閉,然後互相通訊,不使用的讀端或寫端必須關閉,請讀者想一想如果不關閉會有什麼問題。

1. 如果所有指向管道寫端的檔案描述符都關閉了(管道寫端的引用計數等於0),

而仍然有程序從管道的讀端讀資料,那麼管道中剩餘的資料都被讀取後,

再次 read 會返回0,就像讀到檔案末尾一樣。

2. 如果有指向管道寫端的檔案描述符沒關閉(管道寫端的引用計數大於0),

而持有管道寫端的程序也沒有向管道中寫資料,這時有程序從管道讀端讀資料,

那麼管道中剩餘的資料都被讀取後,再次 read 會阻塞,

直到管道中有資料可讀了才讀取資料並返回。

考慮到如下**

#include#include

#include

#include

int main(void

)

if((pid=fork())<0

)

if(pid>0

)

else

return0;

}

父程序關閉了讀埠,通過寫埠向pipe中寫入了hello world。然後父程序結束。關閉相關檔案(讀寫)描述符

子程序在關閉寫埠的時候,父程序結束時候,寫檔案描述符引用計數為0。所以子程序再次讀取後返回0。子程序結束退出。

子程序在不關閉寫埠的時候,父程序結束時候,寫檔案描述符引用計數為1(自己的沒關閉)。所以子程序再次讀取時候陷入阻塞狀態。

因為父程序是在shell下執行的。所以當父程序結束時候,shell程序認為命令執行結束了,於是列印shell提示符,而子程序等待讀取輸入。

父程序已經結束,不會給他輸入資料,而子程序本身只是為了讀取而不是向管道寫資料。所以子程序一直在後台執行,通過ps命令可以檢視到子程序資訊。

所以,子程序只用到讀端,因而把寫端關閉。防止造成子程序做無用功。。。

關於linux下pipe管道的用法

管道主要用於程序之間的通訊,而pipe管道主要用於具有親戚關係的程序之間進行通訊,也叫匿名管道。以下是幾個測試demo 1,通過主程序作媒介來實現兩個子程序之間的通訊 思路 主程序與兩個子程序之間分別建立管道,乙個用於從子程序輸入資料到主程序,另乙個管道用於從子程序輸出資料到另乙個子程序,如下 in...

linux 管道關閉無用的寫入端

管道的讀寫是是符合生產者 消費者模型。寫入內容對應於生產內容 讀取管道對應於消費內容。當所有的生產者都退場以後,消費者應當有方法判斷這種情況,俄日不是傻傻等待已經不存在的生產者繼續生產,以至於陷入永久的阻塞 如何判斷?答案是通過檔案結束識別符號eof。當對管道的讀取端呼叫read函式返回0 時,就意...

關於remote訪問中的flex端配置問題

剛剛開始使用blazeds可能會有個疑問。tomcat伺服器是必須配置的嗎?如果前台後台分開,怎麼開發。其實伺服器不是必須配置的,配置了那個伺服器,就會在 附加編譯引數 加入這樣一句 services 專案的tomcat路徑 web inf flex services config.xml 這個的目...