简体   繁体   English

UNIX文件描述符重用

[英]UNIX File Descriptors Reuse

Though I'm reasonably used to UNIX and have programmed on it for a long time, I'm not used to file manipulation. 虽然我已经习惯使用UNIX并且已经对它进行了很长时间的编程,但我并不习惯于文件操作。

I know that 0/1/2 file descriptors are standard in, out, and error. 我知道0/1/2文件描述符是标准输入,输出和错误。 I'm aware that whenever a process opens a file, it is given a descriptor with the smallest value that isn't yet used - and I understand some things about using dup/dup2. 我知道无论何时进程打开一个文件,它都会被赋予一个具有最小值但尚未使用的描述符 - 我理解使用dup / dup2的一些事情。

I get confused about file descriptors between processes though. 我对进程之间的文件描述符感到困惑。 Does each process have its own 0/1/2 descriptors for in/out/error or are those 3 descriptors shared between all processes? 每个进程是否有自己的0/1/2描述符用于输入/输出/错误,还是在所有进程之间共享的3个描述符? How come you can run 3 programs in 3 different shells and they all get only their programs output if they are shared? 为什么你可以在3个不同的shell中运行3个程序,如果它们被共享,它们都只得到它们的程序输出?

If two programs open myfile.txt after start-up, will they both use file descriptor #3, or would the second program use #4 since 3 was taken? 如果两个程序在启动后打开myfile.txt,它们都会使用文件描述符#3,还是第二个程序会使用#4从3开始?

I know I asked the same question in a couple ways there, but I just wanted to be clear. 我知道我在几个方面问了同样的问题,但我只是想清楚一点。 The more detail the better :) I've never run into problems with these things while programming, but I'm reading through a UNIX book to understand more and I suddenly realized this confused me a lot and I'd never though about it in detail before. 越详细越好:)编程时我从来没有遇到过这些问题,但我正在阅读一本UNIX书来了解更多,我突然意识到这让我很困惑,我从来没有在细节之前。

Each file descriptor is local to the process. 每个文件描述符都是进程的本地描述符。 However, some file descriptors can refer to the same file - for example, if you create a child process using fork() it would share the files opened by the parent. 但是,某些文件描述符可以引用同一个文件 - 例如,如果使用fork()创建子进程,它将共享父进程打开的文件。 It would have its own set of file descriptors, initially identical to the parent's ones, but they can change with closing/dup-ing, etc. 它将拥有自己的一组文件描述符,最初与父代的文件描述符相同,但它们可以通过关闭/复制等进行更改。

If two programs open the same file, in general they get separate file descriptors, pointing to separate internal structures. 如果两个程序打开同一个文件,通常它们会获得单独的文件描述符,指向不同的内部结构。 However, using certain techniques ( fork , FD passing, etc.) you can have file descriptors in different processes point to the same internal entity. 但是,使用某些技术( fork ,FD传递等),您可以让不同进程中的文件描述符指向同一个内部实体。 Generally, though, it is not the case. 但一般情况并非如此。

Answering your question, both programs would have FD #3 for newly open file. 回答你的问题,这两个程序都有FD#3用于新打开的文件。

File descriptors in Unix (normally) persist through fork() and exec() calls. Unix中的文件描述符(通常)通过fork()和exec()调用持久化。 So yes, several processes can share file descriptors. 所以是的,几个进程可以共享文件描述符。

For example, a shell might do a command like: 例如,shell可能会执行如下命令:

foo | bar

In this case, foo's stdout must be connected to bar's stdin. 在这种情况下,foo的stdout必须连接到bar的stdin。 To do this, the shell will most likely use pipe() to create reader- and writer file descriptors. 为此,shell很可能使用pipe()来创建读取器和写入器文件描述符。 It fork()s twice. 它fork()两次。 The descriptors persist. 描述符仍然存在。 The fork() which will call up foo, will close(1); 将调用foo的fork()将关闭(1); dup(writer_fd); DUP(writer_fd); to make writer_fd descriptor 1. It will then exec(), and process foo will output to the pipe we created. 制作writer_fd描述符1.然后它将执行exec(),并且进程foo将输出到我们创建的管道。 For bar, we close(0); 对于酒吧,我们关闭(0); dup(reader); DUP(读取器); then exec(). 然后是exec()。 And voila, foo will output to bar. 瞧,foo会输出到bar。

Don't confuse the file descriptors with the resources they represent. 不要将文件描述符与它们所代表的资源混淆。 You can have ten different processes, each with a file descriptor of '3' open, and each refer to a different open file. 您可以有十个不同的进程,每个进程的文件描述符为“3”,并且每个进程都引用一个不同的打开文件。 When a process does I/O using its file descriptor, the OS knows which process is doing the I/O and is able to disambiguate which file is being referred to. 当进程使用其文件描述符执行I / O时,操作系统知道哪个进程正在执行I / O并且能够消除所引用的文件的歧义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM