進程間通信:每個進程都有各自的地址空間,所以進程之間交換數據就需要通過內核,將數據拷貝到內核中,然後另一個進程進行讀取,這種方式成爲進程間通信。
★創建管道
include <unistd.h>
int pipe(int filedes[2]);
其中,參數filedes參數傳出給用戶程序兩個文件描述符,filedes[0]指向管道的讀端,filedes[1]指向管道的寫端。
——管道特點:
(1)管道是依賴於文件系統的。
(2)父進程的文件描述表可以被子進程繼承所以只允許有血緣關係的進程相互通信。
(3)管道只能單向通信,如果想雙向通信,需再設置一個管道。
(4)管道是一種面向字節流的傳輸符。
(5)當進程結束時,管道就會被操作系統回收。
★管道通信
——兩個進程的通信:
①父進程調用pipe開闢管道,得到兩個文件描述符指向管道的兩端。
②父進程調用fork創建子進程,那麼子進程也有兩個文件描述符指向同一管道。
③父進程關閉管道讀端,子進程關閉管道寫端。父進程可以往管道里寫,子進程可以從管道里讀,管道是用環形隊列實現的,數據從寫端流入從讀端流出,這樣就實現了進程間通信。
例:
運行結果:
幾種特殊情況:
(1)如果所有指向管道寫端的文件描述符都關閉了,而仍然會有進程從管道的讀端讀數據,那麼當管道中的數據被讀取完之後,再返回0,就像讀到文件末尾一樣。
例:
運行結果:
(2)如果有指向管道寫端的文件描述符沒關閉,而持有管道寫端的進程沒有向管道中寫數據,這時有進程從管道讀端讀數據,那麼管道中剩餘的數據被讀取後,再次read會被阻塞,直到管道中有數據可讀了纔讀取數據並返回。
例:將上面的代碼進行更改:
(3)如果所有指向管道讀端的文件描述符都關閉了,這時有進程向管道的寫端write,那麼該進程會收到信號SIGPIPE,通常會導致進程異常終止。
例:將上面的代碼進行更改:
(4)如果有指向管道讀端的文件描述符沒關閉,而持有管道讀端的進程也沒有從管道中讀數據,這時有進程向管道寫數據,那麼在管道被寫滿時再次write會阻塞,直到管道中有空位置了才寫入數據並返回。
本文出自 “無心的執着” 博客,轉載請與作者聯繫!