linux下程序間通訊之管道

2021-08-04 05:16:23 字數 2425 閱讀 9855

管道:

管道是ipc最基本的一種實現機制。我們都知道在linux下「一切皆檔案」,其實這裡的管道就是乙個檔案。管道實現程序通訊就是讓兩個程序都能訪問該檔案。而管道又分為

匿名管道

和命名管道

。匿名管道(piep):

匿名管道的建立:

int pipe(int pipefd[2])
呼叫pipe函式時在核心中開闢一塊緩衝區(稱為管道)用於通訊,它有乙個讀端乙個寫端,然後通過pipe引數傳出給使用者程式兩個檔案描述符,pipe[0]指向管道的讀端,pipe[1]指向管道的寫端。所以管道在使用者程式看起來就像乙個開啟的檔案,通過read(pipe[0]),或者write(pipe[1]);向這個檔案讀寫資料其實是在讀寫核心緩衝區。pipe函式呼叫成功返回0,呼叫失敗返回-1。

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

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

3、父程序官渡管道讀端,子程序關閉管道寫端。父程序可以往管道裡寫,子程序可以從管道裡,這樣就實現了程序間通訊。

#include #include #include #include int main()

pid_t id = fork();

if(id < 0)

else if(id == 0)

}else

if(waitpid(id, null, 0)<0)

return 3;

}return 0;

}

管道的特點:

(1)、單向性

(2)、管道(匿名)只能在具有血緣關係的程序間通訊(祖父程序開闢管道,然後fork出子程序和孫子程序他們都有管道的檔案描述符從而進行通訊)

(3)、管道的生命週期隨程序

(4)、管道通訊是面向位元組流

(5)、自帶同步機制

問題:如果只開乙個管道,但是父程序不關閉讀端,子程序不關閉寫端,雙方都保留讀寫端,為什麼不能實現雙向通訊?

答:管道的讀寫端是通過開啟的檔案描述符來傳遞的,因此要通訊的兩個程序必須從他們的公共祖先那裡繼承管道的檔案描述符。

使用管道的4中特殊情況:

(1)、如果所有指向管道寫端的檔案描述符都關閉了,而仍然有程序從管道的讀端讀資料,那麼檔案內的所有內容被讀完後再次read就會返回0,就像讀到檔案結尾。

(2)、如果有指向管道寫端的檔案描述符沒有關閉(管道寫段的引用計數大於0),而持有管道寫端的程序沒有向管道內寫入資料,假如這時有程序從管道讀端讀資料,那麼讀完管道內剩餘的資料後就會阻塞等待,直到有資料可讀才讀取資料並返回。

(3)、如果所有指向管道讀端的檔案描述符都關閉,此時有程序通過寫端檔案描述符向管道內寫資料時,則該程序就會收到sigpipe訊號,並異常終止。

(4)、如果有指向管道讀端的檔案描述符沒有關閉(管道讀端的引用計數大於0),而持有管道讀端的程序沒有從管道內讀資料,假如此時有程序通過管道寫段寫資料,那麼管道被寫滿後就會被阻塞,直到管道內有空位置後才寫入資料並返回。

命名管道(fifo):

管道的乙個不足之處是沒有名字,因此,只能用於具有親緣關係的程序間通訊,在命名管道(named pipe或fifo)提出後,該限制得到了克服。fifo不同於管道之處在於它提供乙個路徑名與之關聯,以fifo的檔案形式儲存於檔案系統中。命名管道是乙個裝置檔案,因此,即使程序與建立fifo的程序不存在親緣關係,只要可以訪問該路徑,就能夠通過fifo相互通訊。值得注意的是,fifo(first input first output)總是按照先進先出的原則工作,第乙個被寫入的資料將首先從管道中讀出。

命名管道的建立

#include int  mknod(const  char*  path, mode_t mod,  dev_t dev);

int mkfifo(const char* path, mode_t mod);

注釋:這兩個函式都能建立乙個fifo檔案,該檔案是真實存在於檔案系統中的。函式 mknod 中引數 path 為建立命名管道的全路徑; mod 為建立命名管道的模式,指的是其訪問許可權; dev為裝置值,改值取決於檔案建立的種類,它只在建立裝置檔案是才會用到。 

返回值:這兩個函式都是成功返回 0 ,失敗返回 -1

命名管道建立完成後就可以使用,其使用方法與管道一樣,區別在於:命名管道使用之前需要使用open()開啟。這是因為:命名管道是裝置檔案,它是儲存在硬碟上的,而管道是存在記憶體中的特殊檔案。但是需要注意的是,命名管道呼叫open()開啟有可能會阻塞,但是如果以讀寫方式(o_rdwr)開啟則一定不會阻塞;以唯讀(o_rdonly)方式開啟時,呼叫open()的函式會被阻塞直到有資料可讀;如果以只寫方式(o_wronly)開啟時同樣也會被阻塞,知道有以讀方式開啟該管道。

Linux下程序間通訊之命名管道

管道實現通訊的方式簡單易懂,但乙個不足之處就是管道沒有名字,因此,只能用於具有親緣關係的程序間通訊,在命名管道 named pipe或fifo 提出後,該限制得到了克服。fifo不同於管道之處在於它提供乙個路徑名與之關聯,以fifo的檔案形式儲存於檔案系統中。命名管道是乙個裝置 檔案,因此,即使程序...

linux程序間通訊之管道通訊

一 命名管道通訊 管道通訊分為 無名管道和有名管道 無名管道是用於父子孫程序,之間有血緣關係 有名管道 用於任意兩個程序 無名管道 1 建立 int pipe int filedis 2 它會建立兩個檔案描述符 filedis 0 用於讀管道 filedis 1 用於寫管道 通常先建立乙個管道,再通...

linux程序間通訊之管道

下面幾節,將分別溫習下linux程序進通訊的幾種機制1 管道 管道是比較古老的程序間的通訊方式。主要有有名管道和無名管道兩種。2 無名管道 它的特點就是 1 只能使用在具有親緣關係的程序之間的通訊 父子程序或者兄弟程序之間 因為只有具有親緣關係的程序才能繼承其建立的檔案描述符。2 是乙個半雙工的通訊...