Linux程序通訊之管道(匿名,命名)

2021-08-02 09:54:46 字數 3210 閱讀 5462

每個程序各⾃自有不同的⽤使用者位址空間,任何⼀乙個程序的全域性變數在另⼀乙個程序中都看不到 所以進 程之間要交換資料必須通過核心,在核心中開闢⼀一塊緩衝區,程序1把資料從⽤使用者空間 拷到核心緩 沖區,程序2再從核心緩衝區把資料讀⾛走,核心提供的這種機制稱為程序間通訊 (ipc,interprocess com)

管道就是程序間通訊最基本的一種通訊方式。

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

#include 

int pipe(pipefd[2]);

管道由父程序建立,得到兩個檔案描述符指向管道的兩端。再由父程序建立子程序,此時,子程序繼承了父程序的檔案描述符表,管道算作乙個公共資源,這樣父子程序都可以看到這塊空間,可以對這塊空間進行讀寫操作。

管道是由pipe函式在系統核心中開闢的一塊公共空間,兩個程序均可訪問這快空間,即形成了程序間的通訊。簡而言之,程序通訊就是一塊公共資源,不同的程序選擇的讀寫方式不同,就造成了程序之間的通訊。管道有兩個埠(可以想象成現實生活中的管子),乙個埠為讀埠,另乙個埠是寫埠,管道的讀寫端通過乙個只有兩個元素的陣列確定,pipe函式的引數pipefd[2],其中pipefd[0]為讀端,pipefd[1]位寫端。

其實,pipefd的兩個成員就相當於檔案描述符表中的stdout和stdin。如圖:

但是,程序間使用匿名管道通訊的缺點也很明顯:

1、只能在有血緣關係的程序間通訊;

2、管道的具有單嚮導通性;

關於第一點,很好理解,即:父程序建立了乙個子程序,那麼這兩個程序就具有血緣關係,所以可以使用匿名管道通訊,或者說子程序又建立了乙個孫子程序,那麼父程序和孫子程序也可以進行基於匿名管道的通訊。

第二個:管道的單嚮導通性,這個性質在稍後講的命名管道也存在。即:若是已經決定由父程序向子程序傳送資料,那麼之後就不可更改,只能由父程序發,子程序收,期間不肯可能由子程序發,父程序收可能性存在。

假設:子程序向父程序傳送資料。

有沒有存在這樣乙個情況,子程序準備傳送的資料為:」hello,father!」,但是在寫完hello或者正在寫,father的時候,父程序來讀取資料,只將hello讀走,或讀走了一些無效資料,這不是就造成了通訊的錯誤嗎?

所以管道自帶了互斥與同步機制,寫端在寫資料且沒有寫完時,讀端是不可能訪問管道這塊公共資源的,就好像有乙個守門人在看著這塊公共資源,有乙個人進去了,另乙個人只能等著。

1、單嚮導通性;

2、只能用於存在血緣關係的程序間通訊;

3、面向資料流;

4、管道的生命週期為「隨程序」;

5、管道為空時,則停止讀取。

何為管道的生命週期「隨程序」?很好理解,即:程序結束,管道消失。

那為什麼管道為空時,要強制停止讀取,因為一直在讀取的操作浪費了系統的資源,系統需要停止這乙個無用的操作。

簡單的**實現:

#include 

#include

#include

int main()

if(0 == id)//子程序

}else

//父程序

命名管道的性質與匿名管道的性質相同,只有幾點不同,但是正是這幾點才是二者的卻別所在。

相同點:

1、單嚮導通性——只要是管道,就擺脫不了這個性質;

2、面向資料流通訊;

3、管道為空,則停止讀取資料;

不同點:

1、生命週期「隨核心」;

2、可以進行不同程序間的通訊,不侷限於只有血緣關係的程序。

命名管道的建立使用mkfifo函式

#include 

#include

int mkfifo(const

char *pathname, mode_t mode);

pathname表示管道的名稱或路徑,mode表示管道的許可權,跟umask的設定相同。

地愛用此函式就會建立乙個命名管道,可以在呼叫此函式後返回建立管道的路徑下面搜尋,就會發現乙個管道檔案,這個現象就表明了命名管道的宣告週期是隨核心的。期間除非手動刪除,否則不會消失。

此時需要編寫兩個檔案,即表示兩個毫不相干的程序,乙個使用寫端寫資料,另乙個使用讀端讀資料。

建立管道完成後,使用open函式開啟管道,使用相應的」o_wdonly」,」o_wronly」來標明建立的讀寫方式。

**實現:

server.c//建立管道並傳送資料

#include

#include

#include

#include

#include

int main()

}int pipefd = open(pipe_name,open_code);//開啟管道

if(pipefd<0)

while(1)

close(pipefd);//關閉管道

return0;}

client.c//讀資料

#include

#include

#include

#include

#include

int main()

while(1)

printf("erver to lient------->read:%s\n",buff);

}return

0;}

server.c寫端:

client.c讀端:

若文中有不準確或不正確之處,請指出,謝謝!

Linux程序通訊 匿名管道

linux程序通訊中最為簡單的方式是匿名管道 匿名管道的建立需要用到pipe函式,pipe函式引數為乙個陣列 表示的檔案描述字。這個陣列有兩個檔案描 述字,第乙個是用 於讀資料的檔案描述符 第二個是用於寫資料的檔案描述符。不能將用於寫的檔案描述 符進行讀操作或者進行讀的檔案描述 符進寫操作,這樣都會...

Linux 程序間通訊之匿名管道

程序間通訊 目的 分類 管道 把乙個程序連線到另乙個程序的乙個資料流稱為管道 匿名管道 include 建立乙個無名管道 intpipe int pipefd 2 pipefd 檔案描述附陣列 pipefd 0 表示讀端,pipefd 1 表示寫端 成功返回0 失敗返回錯誤 呼叫pipe函式的程序 ...

linux管道通訊之匿名管道

管道檔案的大小始終是為0,更多的時候,它只是起乙個標識作用,標識核心中的那塊快取區。就會出現所謂的匿名管道 比如父子程序之間的通訊 使用pipe建立匿名管道,看不到pipe檔案。pipe int fds 2 fds 0 讀,fds 1 寫 返回2個檔案描述符,乙個讀檔案描述符,乙個寫檔案描述符。匿名...