從已有的進(jìn)程創(chuàng)建新進(jìn)程,其用途是有限的,它們無法進(jìn)行進(jìn)程間通信。進(jìn)程間通信允許運(yùn)行在同一CPU上的并且祖先相同的進(jìn)程交換信息。最成熟的進(jìn)程間通信的形式稱為管道,它由兩個(gè)文件描述符組成,一個(gè)用于讀信息,另一個(gè)用于寫信息。有兩種管道:半雙工和全雙工。半雙工管道僅能在一個(gè)方向上傳遞信息,而全雙工管道可在兩個(gè)方向上傳遞信息。1
簡介管道是Linux/UNIX系統(tǒng)中比較原始的進(jìn)程間通信形式,它實(shí)現(xiàn)數(shù)據(jù)以一種數(shù)據(jù)流的方式,在多進(jìn)程間流動(dòng)。在系統(tǒng)中其相當(dāng)于文件系統(tǒng)上的一個(gè)文件,來緩存所要傳輸?shù)臄?shù)據(jù)。管道通信是最常見的通信方式之一,其是在兩個(gè)進(jìn)程之間實(shí)現(xiàn)一個(gè)數(shù)據(jù)流通的管道,該管道可以是雙向或單向的。1
我們將僅能在一個(gè)方向上傳遞信息的管道稱為半雙工管道,將可在兩個(gè)方向上傳遞信息的管道稱為全雙工管道。管道是一種很經(jīng)典的進(jìn)程之間的通信方式,其優(yōu)點(diǎn)在于簡單易用,其缺點(diǎn)在于功能簡單,有很多限制。
管道及介紹管道在某些特性上不同于文件,例如,當(dāng)數(shù)據(jù)讀出后,則管道中就沒有數(shù)據(jù)了,但文件沒有這個(gè)特性。 2
匿名半雙工管道在系統(tǒng)中是沒有實(shí)名的,并不可以在文件系統(tǒng)中以任何方式看到該管道。它只是進(jìn)程的一種資源,會隨著進(jìn)程的結(jié)束而被系統(tǒng)清除。管道通信是在UNIX系統(tǒng)中應(yīng)用比較頻繁的一種方式,例如使用grep查找。2其代碼如下:
# ls | grep ipc
上述命令中使用的是半雙工管道,即grep命令的輸入是ls命令的輸出。管道從數(shù)據(jù)流動(dòng)方向上又分全雙工管道以及半雙工管道,當(dāng)然全雙工管道現(xiàn)在某些系統(tǒng)還不支持,其在具體的實(shí)現(xiàn)過程中也只是在文件打開的方式上有一點(diǎn)區(qū)別(在操作規(guī)則上也有一些不同,全雙工管道要相比半雙工復(fù)雜的多)。2
匿名管道沒有名字,對于管道中使用的文件描述符沒有路徑名,也就是不存在任何意義上的文件,它們只是在內(nèi)存中跟某一個(gè)索引節(jié)點(diǎn)相關(guān)聯(lián)的兩個(gè)文件描述符。匿名半雙工管道的主要特性如下:
● 數(shù)據(jù)只能在一個(gè)方向上移動(dòng)。
● 只能在具有公共祖先的進(jìn)程間通信,即或是父子關(guān)系進(jìn)程間、或是在兄弟關(guān)系進(jìn)程間通信。
盡管有如此限制,半雙工管道還是最常用的通信方式。Linux環(huán)境下使用pipe函數(shù)創(chuàng)建一個(gè)匿名半雙工管道,其函數(shù)原型如下:
#include
int pipe(int fd[2]);
參數(shù)int fd[2]為一個(gè)長度為2的文件描述符數(shù)組,fd[0]是讀出端,fd[1]是寫入端,函數(shù)的返回值為0表示成功,–1表示失敗。當(dāng)函數(shù)成功返回,則自動(dòng)維護(hù)了一個(gè)從fd[1]到fd[0]的數(shù)據(jù)通道。2
管道創(chuàng)建半雙工管道的創(chuàng)建一般會從程序父進(jìn)程中先使用pipe函數(shù)創(chuàng)建新管道,在調(diào)用fork函數(shù)創(chuàng)建子進(jìn)程,在父子進(jìn)程中維護(hù)管道的數(shù)據(jù)流向,最后,在程序退出時(shí)及時(shí)關(guān)閉管道的兩端。
管道操作的基本流程為:先創(chuàng)建一個(gè)管道,使用fork創(chuàng)建子進(jìn)程, 在父子進(jìn)程中關(guān)閉不需要的文件描述符使用管道通信,程序結(jié)束。2
使用注意事項(xiàng)當(dāng)使用半雙工管道時(shí),任何關(guān)聯(lián)的進(jìn)程都必須共享一個(gè)相關(guān)的祖先進(jìn)程。因?yàn)楣艿来嬖谟谙到y(tǒng)內(nèi)核之中,所以任何不在創(chuàng)建管道的進(jìn)程的祖先進(jìn)程之中的進(jìn)程都將無法尋址它。而任命名管道中卻不是這樣。
雖然可以通過打開兩個(gè)管道來創(chuàng)建一個(gè)雙向的管道。但需要在產(chǎn)進(jìn)程中正確地設(shè)置文件描述符。必須在系統(tǒng)調(diào)用fork()中調(diào)用pipe(),否則子進(jìn)程不會繼承文件描述符。3
本詞條內(nèi)容貢獻(xiàn)者為:
王偉 - 副教授 - 上海交通大學(xué)