Linux程序間通訊 管道通訊

2021-10-24 02:12:02 字數 3724 閱讀 9388

1. 管道簡介

管道是linux中程序間通訊的一種方式,它把乙個程式的輸出直接連線到另乙個程式的輸入。管道主要包括兩種:無名管道和有名管道

無名管道

有名管道

linux中管道通訊的一種原始方法

對無名管道的一種改進

只能用於具有親緣關係的程序之間通訊

可以使互不相關的兩個程序實現彼此通訊

單工的通訊模式,有固定的讀端和寫端

開啟管道時可指定讀寫方式

可使用read()/write(),不屬於檔案系統只存在於記憶體中

通過檔案io操作,內容存放在記憶體中

無名管道和有名管道

2. 無名管道

2.1 無名管道建立與關閉

無名管道時基於檔案描述符的通訊方式。當乙個管道建立時,它會建立兩個檔案描述符: fd[0] 和 fd[1],其中fd[0]固定用於讀管道,fd[1]固定用於寫管道。從而構成了乙個單向的資料通道。

建立管道可以通過 pipe()來實現

/*****pipe()函式*****/

函式原型:int

pipe

(int fd)

傳 入 值:fd[

]是包含兩個元素的陣列,存放管道對應的檔案描述符

返 回 值:成功返回0;失敗返回-

1

管道關閉時只需用 close() 函式將兩個檔案描述符關閉即可

2.2 無名管道讀寫

用pipe()函式建立的管道兩端處於乙個程序中。由於管道主要是用於不同程序間的通訊,通常先是建立乙個管道,再呼叫 fork() 函式建立乙個子程序,該子程序會繼承父程序的管道。這時父子程序管道的檔案描述符對應關係如下左圖所示。

由於無名管道時單工的工作模式,即程序要麼只能讀管道,要麼只能寫管道。因此只能使用其中乙個(例如可約定父程序讀管道,子程序寫管道)。這樣就應該把不使用的讀端或寫端的檔案描述符關閉。如下右圖所示,父程序的寫端和子程序的讀端關閉,建立了一條「子程序寫入父程序讀取」的管道。

管道讀寫注意點

例項程式

/*****pipe.c*****/

#include

#include

#include

#include

#include

#define max_data_len 256

intmain()

if((pid =

fork()

)==0)

else

if(pid >0)

}

編譯並執行後,結果如下

linux@linux-virtual-machine:

~/andy/proc$ .

/pipe

parent wrote 17 bytes:

'pipe test program'

17 bytes read from the pipe is 'pipe test program'

3. 有名管道

3.1 有名管道的建立

有名管道(fifo)可以使用 mkfifo() 函式來建立,該函式類似於檔案中的 open() 操作,可以指定管道的路徑和訪問許可權。管道建立成功後,就可以使用 open()、read() 和 write() 這些函式了。與普通檔案一樣,對於為讀而開啟的管道可以在 open() 中設定 o_rdonly,對於為寫而開啟的管道可在 open() 中設定 o_wronly

/*****mkfifo()函式*****/

函式原型:int

mkfifo

(const

char

*filename, mode_t mode)

傳 入 值:filename 要建立的管道名

mode 管道的訪問許可權

返 回 值:成功返回0;失敗返回-

1

fifo出錯資訊

含義eaccess

引數filename所指定的目錄路徑無可執行的許可權

eexist

引數filename所指定的檔案已存在

enametoolong

引數filename的路徑名稱太長

enoent

引數filename包含的檔案不存在

enospc

檔案系統的剩餘空間不足

enotdir

引數filename路徑中的目錄存在但卻非真正的目錄

erofs

引數filename指定的檔案存在於唯讀檔案系統內

例項程式

/*****fifo_write.c*****/

#include

#include

#include

#include

#include

#define myfifo "/tmp/myfifo"

//有名管道檔名

intmain

(int argc,

char

*ar**)

if((fd =

open

(myfifo,o_wronly)

)<0)

if((nwrite =

write

(fd,ar**[1]

,strlen

(ar**[1]

+1))

)>0)

//向管道寫入字串

printf

("write '%s' to fifo\n"

,ar**[1]

);close

(fd)

;return0;

}/*****fifo_read.c*****/

/*標頭檔案和巨集定義同fifo_write.c*/

intmain()

if((fd =

open

(myfifo,o_rdonly)

)<0)

while(1

)close

(fd)

;return

0}

把以上兩個程式分別在兩個終端執行。先啟動讀管道程式,讀程序在建立管道後就開始迴圈地從管道裡讀出內容。如果當前管道中沒有資料,則一直阻塞到寫管道程序向管道寫入資料。在執行了寫管道程式後,讀程序能夠從管道讀出使用者的輸入內容,程式執行結果如下

終端一如下

linux@linux-virtual-machine:

~/andy/proc$ .

/fifo_read

read 'fifo' from fifo

read 'test' from fifo

終端二如下

linux@linux-virtual-machine:

~/andy/proc$ .

/fifo_write fifo

write 'fifo' to fifo

linux@linux-virtual-machine:

~/andy/proc$ .

/fifo_write test

write 'test' to fifo

Linux 程序間通訊 管道通訊

管道是 單向的 先進先出的,它把乙個程序的輸出和另乙個程序的輸入連線在一起,乙個程序 寫程序 在管道的尾部寫入資料,另乙個程序 讀程序 從管道的頭部讀出資料 資料被乙個程序讀出之後,將被從管道中刪除,其它讀程序將不能再讀到這些資料,管道提供了 簡單的流控制機制,程序試圖讀空管道時,程序將阻塞,同樣,...

Linux程序間通訊 管道

linux程序間通訊機制 1.同一主機程序間通訊機制 unix方式 有名管道fifo 無名管道pipe 訊號signal systemv方式 訊號量 訊息佇列 共享記憶體 2.網路通訊 rpc remote procedure call socket 管道管道是程序間通訊中最古老的方式,它包括無名管...

Linux程序間通訊 管道

管道 管道是一種最基本的程序間通訊機制,由pipe函式建立 include intpipe int filedes 2 呼叫pipe函式時在核心中開闢一塊緩衝區 稱為管道 用於通訊,它有乙個讀端乙個寫端,然後通過filedes引數傳出給使用者程式兩個檔案描述符,filedes 0 指向管道的讀端,f...