2012-08-06 105 views
10

我有這種情況。我們是否需要關閉顯式寫入端已經關閉的管道的讀取端?

  1. 我創建了一個管道。

  2. 分叉一個子進程。

  3. 子進程關閉讀管道明確末和寫入管道和出口的寫入結束,但不關閉任何東西(退出應該關閉代子的所有打開的文件/管描述,我相信)。

  4. 父關閉管道明確寫端和使用fgets直到fgets返回NULL管道的讀端讀取。即它完全讀取。

現在我的問題是,爲什麼父母需要顯式關閉管道的讀取結束一旦完成閱讀?一旦從讀取端讀取完整數據後,系統是否明智地刪除管道?

我力明確關閉讀端在父母和我有Too many file descriptors錯誤遲早會同時打開多個管。我的假設是,一旦寫入端關閉並且數據已從讀取端完全讀取,系統會自動刪除管道。因爲你不能從管道上兩次!

所以,什麼不刪除數據一旦管道系統背後的理念已經完全讀寫結束時關閉?

+0

「因爲你不能從一個管道兩次!」? – 2012-08-06 10:31:11

+0

@KerrekSB我的意思是你可以兩次讀相同的管道,但會在第二次看到EOF嗎? – 2012-08-06 10:37:47

回答

7

你是正確的,系統將關閉該管道一旦孩子退出的寫入結束。但是,如果孩子fork或者將寫入結尾的副本傳遞給另一個進程,那麼可能會打開該管道的另一個寫入端。

它仍然是正確的,該系統將能夠告訴當在管的一端所有的描述符都關閉(顯式或因爲擁有的進程退出)。關閉管道另一端的那些仍然沒有意義,因爲當父進程試圖關閉管道末端的描述符時會導致混淆;或者:

  • fd已被系統關閉,在這種情況下,當它嘗試關閉已經關閉的fd時出現錯誤;或者
  • fd已被重用,這更糟,因爲它現在正在關閉一個完全不相關的fd。

從系統的角度來看,一旦一端的所有描述符都關閉,它可能已經丟棄了管道,因此您不必擔心那裏的低效率。更重要的是,用戶空間過程應該具有一致的體驗,這意味着除非特別要求,否則不要關閉描述符。

5

系統不關閉文件描述符,直到進程退出。對於管道以及任何其他文件描述符都是如此。

有一個不帶數據和封閉的文件描述符管道(或任何其他文件)之間有很大的區別。
當文件描述符關閉時,系統可以將其編號重新用於新的文件描述符。然後,當你讀書時,你會得到別的東西。因此,在關閉文件描述符後,您不能再使用它了。

現在設想一旦沒有更多的數據,系統會自動關閉文件描述符。這將使該號碼可供重複使用,並且隨後的無關聯開放可能會得到它。現在,不知道沒有更多數據的讀者將從它認爲是管道中讀取數據,但實際上將從另一個文件中讀取數據。

相關問題