程序間通訊 管道

2021-08-17 08:11:21 字數 3366 閱讀 7318

程序間通訊----(ipc)interprocess communication

一:管道

管道(包括無名管道和命名管道),通常指無名管道,是 unix 系統ipc最古老的形式。

[含義]:管道是乙個程序的資料流到另乙個程序的通道,即乙個程序的資料的輸出作為另乙個程序的資料的輸入,管道起到了橋梁的作用。

比如:當我們輸入: ls -l | cat test .其中ls和cat是兩個程序,|代表管道,意思是執行ls -l程序,並將輸出結果作為cat test程序的輸入,cat程序將輸入的結果列印在螢幕上:

[本質]:匿名管道之所以可以通訊的本質在於,父程序fork子程序,父子程序各自擁有乙個檔案描述符表,但是兩者的內容是一樣的,既然內容一致,那麼指向的就是同乙個管道,即父子程序看到了同乙份公共資源。

1、特點:

它是半雙工的(即資料只能在乙個方向上流動),具有固定的讀端和寫端。若要進行雙向通訊,需要兩個管道

它只能用於具有共同祖先的程序之間的通訊(也是父子程序或者兄弟程序之間)。

它可以看成是一種特殊的檔案,對於它的讀寫也可以使用普通的read、write 等函式。但是它不是普通的檔案,並不屬於其他任何檔案系統,並且只存在於記憶體中。

一般而言,程序退出,管道釋放,管道通訊依賴於檔案系統,所以管道的生命週期隨程序

一般而言,核心會對管道操作進行同步和互斥,保證讀寫順序一致

管道的通訊被稱為面向位元組流

當沒有資料可讀時,read呼叫阻塞,即程序暫停執行,一直等到有資料來到為止

當管道滿的時候,write呼叫阻塞,直到有程序讀走資料.

1)如果所有指向管道寫端的檔案描述符都關閉了(管道寫端的引用計數為0),而仍然有程序從管道的讀端讀資料,那麼管道中剩餘的資料被讀取後,再次read會返回0,就像讀到檔案末尾一樣。

2)如果有指向管道寫端的檔案描述符沒關閉(管道寫端的引用計數大於0),而持有管道寫端的程序也沒用向管道中寫資料,這時有程序從管道讀端讀資料,那麼管道中剩餘的資料被讀取後,再次read會阻塞,直到管道中有資料可讀了才讀取資料並返回。

3)如果所有指向管道讀端的檔案描述符都關閉了(管道讀端的引用計數等於0),這時有程序向管道的寫端write,那麼該程序會收到訊號sigpipe,通常會導致程序異常終止。

4)如果有指向管道讀端的檔案描述符沒有關閉(管道讀端的引用計數大於0),而持有管道讀端的程序也沒有從管道中讀取資料,這是有程序向管道的寫端寫入資料,那麼在管道被寫滿時,再次write會阻塞,直到管道中有空位置了才寫入資料並返回。

1 #include 2

int pipe(int fd[2]); //

返回值:若成功返回0,失敗返回-1

當乙個管道建立時,它會建立兩個檔案描述符:fd[0]為讀而開啟,fd[1]為寫而開啟。如下圖:

要關閉管道只需將這兩個檔案描述符關閉即可

單個程序中的管道幾乎沒有任何用處。所以,通常呼叫 pipe 的程序接著呼叫 fork,這樣就建立了父程序與子程序之間的 ipc 通道。如下圖所示:

若要資料流從父程序流向子程序,則關閉父程序的讀端(fd[0])與子程序的寫端(fd[1]);反之,則可以使資料流從子程序流向父程序。

1.建立管道

2.建立子程序

3.子程序寫資料

4.父程序讀資料

1 #include2 #include3 #include4 #include5 #include6 int main()

12 pid_t pid;

13 pid=fork();

14 if(pid==-1)

17 if(pid==0)

23 if(pid>0);

26 read(fd[0],buf,10);

27 printf("buf=%s\n",buf);

28 }

29 return 0;

30 }

以上我們介紹的是匿名管道,現在我們來看一下命名管道

我們會發現,匿名管道有乙個限制就是只能用於具有共同祖先的程序,如果我們想在不相關的程序之間交換資料,可以使用fifo檔案來做這項工作,它就是我們經常提到的命名管道(命名管道是一種特殊的檔案型別),命名管道之所以可以實現程序間通訊在於通過同乙個路徑名而看到同乙份資源,這份資源以fifo的檔案形式存在於檔案系統中。fifo總是按照先入先出的原則工作,第乙個被寫入的資料將首先從管道讀出。

命名管道對應磁碟上的乙個檔名,一旦建立起檔名與管道的關係,刪掉檔案是沒有關係的

命名管道可以在命令列上建立-----   $ mkfifo filename

命名管道也可以從程式裡建立-------  int mkfifo(const char *filename,mode_t mode);

建立命名管道

int main(int argc,char *argv)
匿名管道由pipe函式建立並開啟

命名管道由mkfifo函式建立,開啟用open

一旦這些工作做好之後,它們具有相同的語義

server_pipe.c

1 #include2 #include3 #include4 #include5 #include6 #include7 int main()

14 int rfd = open("mypipe",o_rdonly);

15 if(rfd<0)

16

19 char buf[1024];

20 while(1)

29 else if(s==0)

33 else

37 }

38 close(rfd);

39 return 0;

40 }

client_pipe.c

1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 int main()

15 char buf[1024];

16 while(1)

27 else if(s<=0)

31 }

32 close(wfd);

33 return 0;

34 }

程序間通訊 管道

include int pipe int fd 2 返回值 若成功,返回0,若出錯,返回 1經由引數fd返回兩個檔案描述符 fd 0 為讀而開啟,fd 1 為寫而開啟。fd 1 的輸出是fd 0 的輸入。else if pid 0 子程序 else else if pid 0 父程序 printf ...

程序間通訊 管道

原文 程序間通訊 管道 管道簡介 常說的管道都是匿名半雙工管道,匿名半雙工管道在系統中是沒有實名的,並不可以在檔案系統中以任何方式看到該管道。它只是程序的一種資源,會隨著程序的結束而被系統清除。管道通訊是在unix系統中應用比較頻繁的一種方式,例如使用grep查詢 ls grep ipc 顧名思義,...

程序間通訊 管道

程序間通訊,又稱為ipc,包含以下型別 半雙工管道fifo 全雙工管道 訊息佇列 訊號 訊號量共享記憶體 套接字socket streams。一,管道是unix系統ipc的最古老形式,他具有兩種侷限性 1 資料只能在乙個方向上流動 2 只能在具有公共祖先的程序之間使用。乙個管道由乙個程序建立,然後該...