2015-05-13 138 views
1

我想了解什麼是在調用fork()及其對爭用的可能影響後重覆文件描述符。相同的文件描述符後fork()

在 「Linux的編程接口」 24.2.1(P517):

當執行fork()的,孩子接收所有的 父母的文件描述符的副本。這些副本以dup()的方式 製作,這意味着父對象和子對象中的對應描述符引用相同的打開文件描述。

當我運行相同的代碼:

#include <unistd.h> 
#include <fcntl.h> 
#include <stdio.h> 
#include <sys/wait.h> 

int main(void) { 
    char* fl = "/tmp/test_fd"; 
    int fd; 
    fd = open(fl, O_CREAT|O_TRUNC|O_WRONLY, 0666); 
    if(!fork()) { 
     printf("cfd=%d\n", fd); 
     _exit(0); 
    } else { 
     int status; 
     printf("ffd=%d\n", fd); 
     wait(&status); 
     close(fd); 
     unlink(fl); 
    } 
} 

我得到相同的文件描述符(多少?)兩個過程:FFD = 3和CFD = 3。但是,使用dup()運行此代碼時:

#include <unistd.h> 
#include <fcntl.h> 
#include <stdio.h> 

int main(void) { 
    char* fl = "/tmp/test_fd"; 
    int cfd, ffd; 
    ffd = open(fl, O_CREAT|O_TRUNC|O_WRONLY, 0666); 
    cfd = dup(ffd); 
    printf("ffd=%d\n", ffd); 
    printf("cfd=%d\n", cfd); 
    close(ffd); 
    unlink(fl); 
} 

我得到不同的文件描述符:ffd = 3和cfd = 4。

然後,我有以下問題:

  1. 什麼意思fork()的創建父的文件描述符的副本
  2. 當兩個進程(父和子)在同一個文件描述符上同時執行像fstat()這樣的操作時,是否存在爭用?
  3. 那麼兩個進程同時執行fstat()和兩個不同的文件描述符指向同一個文件呢?
+0

[this](http://stackoverflow.com/a/11734354/4178025)相關的問題可能有幫助 – Diego

回答

3

當您看到「複製文件描述符」這個短語時,您需要將其理解爲「創建指向另一個指向的同一事物的新文件描述符」。

所以,當你複製fd 3時,你會得到fd 4.這些數字不是相同的,但它們確定了同一個對象。

在fork的情況下,您必須記住文件描述符的含義包含在進程中。許多進程都有一個有效的fd 3,但它們並不都指向同一個對象。用叉子,你有fd 3的副本也是fd 3,但是在不同的過程中,所以這3個不是固有的相同;它們是相同的,因爲fork製作了一個副本。

您可以關閉fd並在子進程中打開一個不同的文件,並且您仍然有兩個進程,其中fd 3有效,但它們不再是同一事物的副本。或者你可以讓孩子重複fd 3來獲得fd 4,然後關閉fd 3,然後你會在父母中擁有fd 3,並且在涉及同一個對象的孩子中擁有fd 4。

在不同的過程中相同的數字並不意味着什麼。

另請注意,文件描述符引用的對象不是文件。文件描述符和文件之間有一些東西,稱爲打開的文件描述。 fork和dup都會導致公開的文件描述被共享。共享的主要結果是噹噹前文件位置(由lseek設置或由readwrite提前)改變時,所有相關文件描述符都會受到影響,並且當標誌(如O_NONBLOCK)發生更改時,所有相關的文件描述符被影響到的。

相反,如果你open同一個文件兩次,你得到指向同一個文件中的兩個文件描述符,而是通過不同打開文件的描述,讓他們有獨立的標誌,並尋求位置。

fstat是一個只讀操作,我不明白你想象的是什麼樣的「爭用」。

+0

感謝您的明確解釋,我沒有考慮到文件描述符的編號是局部的該過程。 – omx