簡介
匿名管道正因為提供的功能很單一,所以它所需要的系統的開銷也就比命名管道小很多,在本地機器上可以使用匿名管道來實現父進程和子進程之間的通信,這裡需要注意兩點,第一就是在本地機器上,這是因為匿名管道不支持跨網路之間的兩個進程之間的通信,第二就是實現的是父進程和子進程之間的通信,而不是任意的兩個進程。然後得話還順便介紹匿名管道的另外一種功能,其通過匿名管道可以實現子進程輸出的重定向。
管道特徵
管道是IPC最基本的一種實現機制。我們都知道在Linux下“一切皆檔案”,其實這裡的管道就是一個檔案。管道實現進程通信就是讓兩個進程都能訪問該檔案。
匿名管道的特徵:
①只提供單向通信,也就是說,兩個進程都能訪問這個檔案,假設進程1往檔案內寫東西,那么進程2 就只能讀取檔案的內容。
②只能用於具有血緣關係的進程間通信,通常用於父子進程建通信
③管道是基於位元組流來通信的
④依賴於檔案系統,它的生命周期隨進程的結束結束(隨進程)
⑤其本身自帶同步互斥效果
匿名管道的使用
匿名管道主要用於本地父進程和子進程之間的通信,在父進程中的話,首先是要創建一個匿名管道,在創建匿名管道成功後,可以獲取到對這個匿名管道的讀寫句柄,然後父進程就可以向這個匿名管道中寫入數據和讀取數據了,但是如果要實現的是父子進程通信的話,那么還必須在父進程中創建一個子進程,同時,這個子進程必須能夠繼承和使用父進程的一些公開的句柄,為什麼呢?因為在子進程中必須要使用父進程創建的匿名管道的讀寫句柄,通過這個匿名管道才能實現父子進程的通信,所以必須繼承父進程的公開句柄。同時在創建子進程的時候,必須將子進程的標準輸入句柄設定為父進程中創建匿名管道時得到的讀管道句柄,將子進程的標準輸出句柄設定為父進程中創建匿名管道時得到的寫管道句柄。然後在子進程就可以讀寫匿名管道了。
Windows作業系統
使用CreatePipe創建匿名管道。使用ReadFile與WriteFile函式來讀寫管道。讀寫操作總是阻塞式。新建進程可繼承管道句柄。
讀管道時收到一個end-of-file,意味著管道的寫端句柄已經關閉。
例子:
使用管道需要注意的4種特殊情況:
•如果所有指向管道寫端的檔案描述符都關閉了,而仍然有進程從管道的讀端讀數據,那么檔案內的所有內容被讀完後再次read就會返回0,就像讀到檔案結尾。
•如果有指向管道寫端的檔案描述符沒有關閉(管道寫段的引用計數大於0),而持有管道寫端的進程沒有向管道內寫入數據,假如這時有進程從管道讀端讀數據,那么讀完管道內剩餘的數據後就會阻塞等待,直到有數據可讀才讀取數據並返回。
•如果所有指向管道讀端的檔案描述符都關閉,此時有進程通過寫端檔案描述符向管道內寫數據時,則該進程就會收到SIGPIPE信號,並異常終止。
•如果有指向管道讀端的檔案描述符沒有關閉(管道讀端的引用計數大於0),而持有管道讀端的進程沒有從管道內讀數據,假如此時有進程通過管道寫段寫數據,那么管道被寫滿後就會被阻塞,直到管道內有空位置後才寫入數據並返回。