Unix內核源碼剖析node
管道是在父進程和子進程之間通訊的機制,由於進程擁有各自獨立的虛擬地址空間,所
以任意進程沒法直接訪問其餘進程擁有的數據。爲了實現進程間的通訊,設計了管道。緩存
管道對文件系統的一部分進行了巧妙的應用,使得進程間的通訊成爲可能,管道首先獲取根磁盤的inode, 而後利用該inode指向的存儲區進行數據交換。這個文件(inode和存儲區域)構成了管道的實體。管道的容量由PIPSIZE
定義於ken/pipe.c
函數
利用管道進行的通訊過程以下:
(1)發送發的進程向管道寫入數據,直到管道被充滿;
(2)切換到接收方的進程,使得從管道讀入數據,已經接收的數據從管道中被刪除;
(3)數據所有讀取後,切換到發送發的進程,返回(1)的處理性能
發送方以與管道相對應的inode[]
元素的地址+1, 接收方以該地址+2爲參數執行sleep()
spa
使用管道的優勢:設計
在進程間傳遞數據也能夠經過臨時文件來實現,與臨時文件相比,使用管道的優勢:
(1)可以使用的塊設備的資源是有限的,管道的容量爲固定的4096
字節,所以,即便用來交換更大容量的數據也不會佔用更多的塊設備區域,而使用臨時文件時候,會佔用與所交換的數據相等容量的塊設備區域
(2)管道所須要的緩衝區的容量小於緩衝區的總容量,利於發揮塊設備緩衝區的緩存功能,並且,當發送方的進程將數據寫入管道後,接收方的進程將立刻進行讀取,塊設備的緩存效果會更加明顯,當使用臨時文件時候,若是須要輸出大於設備緩衝區容量的文件,緩衝區所帶來的緩存效果將所以受到影響;
可是,當使用管道,且執行進程由發送方切換到接收方時候,若是存在執行優先級更高的進程,且該進程也使用了塊設備的緩衝區的時候,則沒法期待緩衝區帶來的緩存效果。此時,雖然性能沒有獲得改善,可是因爲數據已經輸出到塊設備,所以對通訊內容自己不會形成影響。3d
管道基於現有的文件系統,實現的成本較低,儘管佔用的資源較少,可是卻實現了進程之間的高速通訊,低投入高產出能夠視爲管道最大的魅力。code
系統調用pipe
用來創建管道通訊,pipe()
是系統調用的處理函數blog
首先在user.u_ofile[]
和file[]
中分配供read
和write
使用的元素,而後獲取根磁盤的inode[]
元素,將供read
和write
使用的file[]
元素指向該inode[]
元素,爲file[]
元素設置表示管道的FPIPE
標誌位進程
read
和write
使用的文件描述符返還給用戶程序,用戶程序對該文件描述符,能夠像對待通常文件同樣進行讀寫,實現管道通訊。
對經過系統調用pipe
取得的文件描述符,能夠像對待通常文件那樣執行系統調用read
和write
,從而實現數據收發
當設置了file[]
元素的FPIPE
標誌位時候,在rdwr()
方法中執行writep()
和readp()
方法
writep()
用於對管道進行寫入處理,由於管道的實體爲文件,因此採用與對待通常文件相同的方式調用writei()
寫入數據,當管道被充滿(4096
字節)時候進入睡眠狀態,若是存在等待管道被寫入數據的進程,則將其喚醒;可是,和通常文件處理不一樣,文件偏移量file.f_offset
不會發生變化