1. 程式人生 > >Linux作業系統中的管道(pipe)使用方法

Linux作業系統中的管道(pipe)使用方法

前面在一段小程式中看到了mkfifo這樣的一個函式,在baidu了一下之後對於程序間通訊產生了一點興趣,所以就小小的研究了一下。
在一個多程序作業系統所提供的執行環境下,可以通過兩種不同的途徑或者說採用兩種不同的策略,來建立起復雜的大型應用系統。一種途徑就是通過一個孤立的,大型的,複雜的程序提供所需的全部服務,另外一種途徑就是通過由若干相互聯絡的,小型的。相對簡單的程序構成的組合來提供所需的功能。早期的作業系統往往傾向與前者,而Unix以及其衍生的各種作業系統往往傾向於後者。相比之下,後者有著各種好處:1.模組化,2.各個程序都得到保護,在相當程度上排除了相互干擾的可能性,3.靈活性更強。
當然這種好處也是要付出代價的,也有缺點,但是相比之下,這種途徑的優點遠遠超出了其缺點。
Unix(從而Linux)嚮應用軟體提供了一些程序間通訊的手段,早期的Unix提供了:管道(pipe),訊號(signal),跟蹤(trace)。
這裡我們只談管道:父程序與子程序,或者兩個兄弟程序之間,可以通過系統呼叫建立起一個單向的通訊管道。但是,這種管道只能由父程序來建立,所以對於子程序來說是靜態的,與生俱來的。管道兩端的程序各自將該管道視作一個檔案。一個程序往通道中寫的內容由另一個程序從通道讀出,通過通道傳遞的內容遵循“先入先出”(FIFO)的規則。每個通道都是單向的,需要雙向通訊時要建立起兩個通道。
下面說一說程序間管道的建立,在這之前我們要說到fork()函式,在Linux系統中一個新的程序是由一個已經存在的程序“複製”出來的,而不是“創造”出來的(而所謂的“建立”實際上就是複製)。
管道機制的主體是系統呼叫pipe(),但是由pipe()所建立的管道的兩端都在同一個程序中,這樣的管道起不到程序間通訊的作用。所以必須在fork()的配合下,才能在父子程序間或者兩個子程序之間建立起程序間的通訊管道。
下面就介紹一下怎樣將管道用於程序間通訊:
(1)程序A建立了一個管道,建立完成時代表管道兩端的兩個已開啟檔案都在程序A中。

(2)程序A通過frok()創建出程序B,在fork()的過程中程序A的開啟檔案表按原樣複製到程序B中。

(3)程序A關閉管道的讀端,而程序B關閉管道的寫段。於是,管道的寫段在程序A中而讀端在程序B中,成為了父子程序之間的通訊管道。

(4)程序A又通過frok()建立程序C,而後關閉其管道寫段而與管道脫離關係,使得管道的寫段在程序C中而讀端在程序B中,成為兩個兄弟程序之間的管道。

人們在認識到管道機制也存在一些缺點和不足。由於管道是一種“無名”,“無形”的檔案,它可以通過fork()的過程創建於“近親” 的程序之間,而不能成為可以在任意兩個程序之間建立通訊的機制,更不可能成為一種一般的,通用的程序間通訊模型,同時,管道機制的這種缺點本身強烈的暗示著人們,只要用“有名”,“有形”的檔案來實現管道,就能克服這種缺點。所以有了管道之後,“命名管道”的出現時必然的。
為了實現“命名管道”,在“普通檔案”,“塊裝置檔案”,“字元裝置檔案”之外,又設立了一種檔案型別,稱為FIFO檔案。對這種檔案的訪問嚴格遵循“先進先出”的原則。這樣就可以像在磁碟上建立一個檔案一樣建立一個命名管道,具體可以使用命令mknod來建立。例如:
% mknod mypipe   p
這裡的引數“p”表示所建立的節點的型別。
我們從——help中可以看出:
  b      create a block (buffered) special file
  c, u   create a character (unbuffered) special file
  p      create a FIFO
至於管道的具體使用,大家可以連線下面的一個網址
http://blog.163.com/zqs1111/blog/static/37203887200946344191