簡介
管道是Linux/UNIX系統中比較原始的
進程間通信形式,它實現數據以一種數據流的方式,在
多進程間流動。在系統中其相當於檔案系統上的一個檔案,來快取所要傳輸的數據。
管道通信是最常見的通信方式之一,其是在兩個進程之間實現一個數據流通的管道,該管道可以是雙向或單向的。
我們將僅能在一個方向上傳遞信息的管道稱為半雙工管道,將可在兩個方向上傳遞信息的管道稱為全雙工管道。管道是一種很經典的進程之間的通信方式,其優點在於簡單易用,其缺點在於功能簡單,有很多限制。
管道及介紹
管道在某些特性上不同於檔案,例如,當數據讀出後,則管道中就沒有數據了,但檔案沒有這個特性。
匿名半雙工管道在系統中是沒有實名的,並不可以在檔案系統中以任何方式看到該管道。它只是進程的一種資源,會隨著進程的結束而被系統清除。管道通信是在UNIX系統中套用比較頻繁的一種方式,例如使用grep查找。其代碼如下:
# ls | grep ipc
上述命令中使用的是半雙工管道,即grep命令的輸入是ls命令的輸出。管道從數據流動方向上又分全雙工管道以及半雙工管道,當然全雙工管道現在某些系統還不支持,其在具體的實現過程中也只是在檔案打開的方式上有一點區別(在操作規則上也有一些不同,全雙工管道要相比半雙工複雜的多)。
匿名管道沒有名字,對於管道中使用的
檔案描述符沒有路徑名,也就是不存在任何意義上的檔案,它們只是在記憶體中跟某一個
索引節點相關聯的兩個檔案描述符。匿名半雙工管道的主要特性如下:
● 數據只能在一個方向上移動。
● 只能在具有公共祖先的
進程間通信,即或是父子關係進程間、或是在兄弟關係進程間通信。
儘管有如此限制,半雙工管道還是最常用的通信方式。Linux環境下使用pipe函式創建一個匿名半雙工管道,其函式原型如下:
#include<unisted.h>
int pipe(int fd[2]);
參數int fd[2]為一個長度為2的
檔案描述符數組,fd[0]是讀出端,fd[1]是寫入端,函式的返回值為0表示成功,–1表示失敗。當函式成功返回,則自動維護了一個從fd[1]到fd[0]的數據通道。
管道創建
半雙工管道的創建一般會從程式父進程中先使用pipe函式創建新管道,在調用fork函式創建子進程,在父子進程中維護管道的數據流向,最後,在程式退出時及時關閉管道的兩端。
使用注意事項
當使用半雙工管道時,任何關聯的進程都必須共享一個相關的祖先進程。因為管道存在於系統核心之中,所以任何不在創建管道的進程的祖先進程之中的進程都將無法定址它。而任命名管道中卻不是這樣。
雖然可以通過打開兩個管道來創建一個雙向的管道。但需要在產進程中正確地設定檔案描述符。必須在系統調用fork()中調用pipe(),否則子進程不會繼承檔案描述符。