我试图了解在调用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。
然后,我有以下问题:
答案 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
设置或由read
和write
提前)更改时,所有相关文件描述符都会受到影响,并且当标记时(如O_NONBLOCK
)已更改,所有相关文件描述符都会受到影响。
相反,如果您open
两次使用相同的文件,则会得到两个引用同一文件的文件描述符,但是通过不同的打开文件描述,因此它们具有独立的标志和搜索位置。
fstat
是一个只读操作,我不知道什么样的&#34;争论&#34;你想象它。