2010-07-05 131 views
4

我從execve的手冊頁讀到,如果進程(A)調用execve,已經打開的文件描述符被複制到新進程(B)。execve()和共享文件描述符

兩個possiblities在這裏出現: -

1)這是否意味着一個新的文件描述符表爲進程B創建的條目被從過程的舊文件描述符表中複製一個

2 )或者進程B獲得進程A的文件描述符表,就像在執行進程A之後不再存在一樣,並且只有在進程B獲得了進程A的文件描述符表後才能關閉已經打開的文件。

其中一個是正​​確的?

回答

5

哪一個是正確的?

#2

雖然你問什麼是更多的OS實現細節,這是很少,如果重要的應用程序,完全透明的應用程序,並取決於操作系統。

通常說,新進程繼承文件描述符。顯然,除了那些有FD_CLOEXEC標誌的設置。即使在#1的情況下,如果我們假定在很短的時間內進程A和B都在內存中(不是真的,那就是fork()領域),那麼複製fd表就可以了。由於進程A將被終止(通過exec()),它的所有文件描述符都將是close()d。這對於進程B中已經複製的文件描述符沒有影響。文件描述符就像指向相應內核結構的指針,其中包含有關文件描述符實際指向的實際信息。複製fd表不會複製底層結構 - 它只複製指針。內核結構包含引用計數器(實現fork()所需的),它在複製時增加,因此知道有多少進程正在使用它。首先在文件描述符上調用close()會減少引用計數器的值。只有當計數器變爲零(不再有進程正在使用該結構)時,OS纔會實際關閉底層文件/套接字/管道/等。 (但是很明顯,即使內核中兩個進程同時存在一段時間,用戶空間應用程序也不能看到,因爲exec()之後的新進程也繼承了原始進程的PID。)

12

execve不會創建新的進程。它將基於文件系統中的可執行文件替換調用進程的程序映像,內存空間等。通過關閉具有close-on-exec標誌設置的描述符來修改文件描述符表;其餘的在execve之前保持打開並處於相同的狀態(當前位置,鎖等)。

您可能會將此與fork上的情況混淆,因爲execve通常在前面加上fork。當進程分叉時,子進程有一個新的文件描述符表,引用與父進程的文件描述符表相同的打開文件描述。

+1

我認爲這是一個嚴重的限制在這裏@ stackoverflow.com雖然兩個答案都是正確的,但我只能將其中一個標記爲綠色。 – Ashish 2010-10-08 12:13:05