fork()之后的相同文件描述符

时间:2015-05-13 22:53:15

标签: fork file-descriptor contention

我试图了解在调用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()与两个指向同一文件的不同文件描述符呢?

1 个答案:

答案 0 :(得分:8)

当您看到短语&#34;复制文件描述符&#34;时,您需要将其理解为&#34;创建一个新的文件描述符,指向另一个指向的相同的东西&#34;

所以当你复制fd 3时,你会得到fd 4.不是相同的数字,但它们识别相同的对象。

对于fork,您必须记住文件描述符的含义包含在进程中。很多进程都有一个有效的fd 3,但它们并不都指向同一个对象。使用fork,你有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是一个只读操作,我不知道什么样的&#34;争论&#34;你想象它。