2014-07-15 53 views
7

我正在閱讀關於UNIX中的管道以進行2個進程之間的進程間通信。我有以下問題是否真的有必要在進程中關閉管道的未使用端

是否真的有必要關閉未使用的管道末端?例如,如果我的父進程正在將數據寫入管道並且子進程正在從管道讀取,是否真的有必要在父進程中關閉管道的讀端並關閉子進程的寫端?如果我不能完成這些目標,是否有任何副作用?爲什麼我們需要關閉這些目標?

+0

我不知道如果它有未定義的行爲,如果有兩個讀取結束,但只有一個實際讀取管道。 –

回答

10

如果你不這樣做,就出現這個問題。在你的例子中,父級創建一個管道寫入孩子。然後它分叉子,但不關閉它自己的讀描述符。這意味着管道上仍有兩個讀取描述符。

如果孩子只有一個孩子,並關閉它(例如通過退出),父母會收到一個SIGPIPE信號,或者如果屏蔽了該信號,則在寫入管道時發生錯誤。

但是,管道(父級)上有第二個讀取描述符。現在,如果孩子退出,管道將保持打開狀態。父節點可以繼續寫入管道,直到它填充完畢,然後下一次寫入將會阻塞(或者如果沒有阻塞,則不寫入就返回)。

因此,通過不關閉父節點的讀描述符,父節點不能檢測到子節點已經關閉了它的描述符。

3

按照手冊頁getdtablesize

每個進程具有固定大小的描述符表,它是保證 具有至少20個時隙。

每個管道在描述符​​表中使用兩個條目。關閉不需要的管道末端可以釋放其中一個描述符。所以,如果你不幸在一個系統中每個進程被限制爲20個描述符,你將會非常積極地釋放不需要的文件描述符。

+1

通常,不關閉文件描述符就像釋放內存一樣。你佔用了很少的系統資源。 1024個文件描述符也有一個共同的(軟)限制。 –

1

管道註定要用作單向通信通道。關閉它們是一種很好的做法,可以避免發送消息中的一些混亂。作者的描述符應該關閉閱讀器,反之亦然。

相關問題