管道是如何進(jìn)行進(jìn)程間通信的
匿名管道和命名管道都是內(nèi)核的文件
匿名管道是Linux系統(tǒng)提供的一個(gè)系統(tǒng)函數(shù),可以通過這個(gè)函數(shù)來進(jìn)行管道的使用
//命令行中 | 也起到管道的作用
a|b
管道背后的原理就是兩個(gè)文件描述符號,一個(gè)管道相當(dāng)于一個(gè)隊(duì)列。有管道的頭和尾,往管道的尾里去寫東西,從管道的頭里去讀東西。這個(gè)隊(duì)列如何控制頭跟尾的呢,就是兩個(gè)文件描述符,來表示管道的兩端,讀取端:fd[0]、寫入端:fd[1]。
在一個(gè)進(jìn)程里創(chuàng)建一個(gè)匿名管道之后呢,大概如下圖所示:

創(chuàng)建了一份管道相當(dāng)于創(chuàng)建了一份緩存,因?yàn)長INUX中是一切皆文件的。
如何讓創(chuàng)建的管道在兩個(gè)進(jìn)程中用,fork()子進(jìn)程,會復(fù)制父進(jìn)程文件描述的結(jié)構(gòu)體,fd數(shù)組也會復(fù)制一份。文件描述符相當(dāng)于指針,子進(jìn)程的復(fù)制相當(dāng)于淺拷貝。
由于管道只能一端寫入另一端讀出。所以通常父進(jìn)程只保留讀取的fd,而子進(jìn)程只保留寫入的fd。

父進(jìn)程和子進(jìn)程各關(guān)閉一個(gè)fd描述符。

在shell里的命令,a和b是平級進(jìn)程。shell首先創(chuàng)建一個(gè)子進(jìn)程a然后在shell和a之間創(chuàng)建一個(gè)管道,然后fork出來了一個(gè)a這樣呢shell與a有通信關(guān)系的,之后shell保留讀取端,a保留寫入端。之后shell再創(chuàng)建一個(gè)b,這樣shell、a、b都指向了同一個(gè)管道, 這樣shell再把它的fd0和fd1都給關(guān)掉,這樣fork出來的b
命名管道
實(shí)現(xiàn)原理和匿名管道差不多,本質(zhì)上都是內(nèi)核的文件。命名管道會寫到磁盤文件里,不相關(guān)的進(jìn)程也能一頭寫一頭讀。