2011-08-19 109 views
3

儘管我對UNIX非常熟悉,並且已經對其進行了很長時間的編程,但我不習慣進行文件操作。UNIX文件描述符重用

我知道0/1/2文件描述符是標準輸入,輸出和錯誤。我意識到,無論何時一個進程打開一個文件,它都會被賦予一個最小值的描述符,這個描述符尚未被使用 - 而且我理解了關於使用dup/dup2的一些事情。

雖然我對過程之間的文件描述符感到困惑。每個進程是否有自己的0/1/2描述符用於輸入/輸出/錯誤,還是3個描述符在所有進程之間共享?你如何在3個不同的shell中運行3個程序,並且如果他們共享,他們都只能得到他們的程序輸出?

如果兩個程序在啓動後打開myfile.txt,它們都會使用文件描述符#3,還是第二個程序會在使用3之後使用#4?

我知道我在那裏以幾種方式問過同一個問題,但我只是想說清楚。越詳細越好:)編程時,我從來沒有遇到過這些問題,但是我正在閱讀一本UNIX書以瞭解更多內容,並且我突然意識到這讓我困惑不已,之前的細節。

+0

如果您在發佈中添加'c'語言標記,您會收到更好的評論。我想我已經多次討論過這個問題,所以搜索'[c]標準輸出描述符'。祝你好運。 – shellter

+0

謝謝,添加標籤 - 我會試着看看其他問題:) –

回答

5

每個文件描述符都是進程本地的。但是,某些文件描述符可以引用同一個文件 - 例如,如果使用fork()創建子進程,它將共享由父進程打開的文件。它有自己的一組文件描述符,最初與父文件相同,但可以通過關閉/複製等方式更改。

如果兩個程序打開同一個文件,通常它們會獲得單獨的文件描述符,指向單獨的內部結構。但是,使用某些技術(如fork,FD傳遞等),可以使不同進程中的文件描述符指向相同的內部實體。不過,一般情況並非如此。

回答你的問題,這兩個程序將有FD#3爲新打開的文件。

3

Unix中的文件描述符(通常)通過fork()和exec()調用持續存在。所以是的,幾個進程可以共享文件描述符。

例如,殼可以做如下命令:

foo | bar 

在這種情況下,Foo的標準輸出必須連接到酒吧的標準輸入。爲此,shell最可能使用pipe()來創建讀寫器文件描述符。它fork()兩次。描述符依然存在。將調用foo的fork()將關閉(1); DUP(writer_fd);編寫writer_fd描述符1.然後執行exec(),並將進程foo輸出到我們創建的管道。對於酒吧,我們關閉(0); DUP(讀取器);然後exec()。瞧,foo會輸出到吧。

+2

流程永遠不會共享描述符。然而,多個文件描述符(在相同的進程或不同的進程中)可以引用相同的「打開文件描述」,其具有諸如當前位置,非阻塞標誌等的共享屬性。 –

3

不要將文件描述符與它們表示的資源混淆。你可以有十個不同的進程,每個進程打開一個文件描述符'3',每個進程指向一個不同的打開文件。當一個進程使用其文件描述符進行I/O操作時,操作系統知道哪個進程正在執行I/O,並能夠消除正在引用哪個文件。