C 寻求有关'的简单描述;文件描述符';在fork()之后
在“Unix环境中的高级编程”第二版中,作者:W.Richard Stevens。第8.3节分叉功能 以下是描述: 父级和子级共享相同的文件偏移量非常重要 考虑一个分叉子进程,然后等待子进程完成。假设两个进程都将写入标准输出作为其正常处理的一部分。如果父对象的标准输出被重定向(可能是通过shell重定向),则当子对象写入标准输出时,子对象必须更新父对象的文件偏移量 我的答复是: {1} 这是什么意思?例如,如果父级的std输出被重定向到“file1”,那么在子级写入之后,子级应该更新什么?父级原始标准输出偏移量或重定向输出(即文件1)偏移量?不会晚一点吧 {2} 更新是如何完成的?通过子显式,通过操作系统隐式,通过文件描述符本身?在fork之后,我认为父级和子级各走各的路,拥有自己的文件描述符副本。那么,子更新如何偏移到父端呢 在这种情况下,子级可以在父级等待时写入标准输出;完成子级后,父级可以继续写入标准输出,知道其输出将附加到子级写入的任何内容。如果父级和子级不共享相同的文件偏移量,则这种类型的交互将更难完成,并且需要父级执行显式操作 如果父级和子级都写入同一个描述符,而没有任何形式的同步,例如让父级等待子级,那么它们的输出将是混合的(假设它是在fork之前打开的描述符)。虽然这是可能的,但这不是正常的操作模式 在fork之后处理描述符有两种常见情况C 寻求有关'的简单描述;文件描述符';在fork()之后,c,unix,fork,file-descriptor,C,Unix,Fork,File Descriptor,在“Unix环境中的高级编程”第二版中,作者:W.Richard Stevens。第8.3节分叉功能 以下是描述: 父级和子级共享相同的文件偏移量非常重要 考虑一个分叉子进程,然后等待子进程完成。假设两个进程都将写入标准输出作为其正常处理的一部分。如果父对象的标准输出被重定向(可能是通过shell重定向),则当子对象写入标准输出时,子对象必须更新父对象的文件偏移量 我的答复是: {1} 这是什么意思?例如,如果父级的std输出被重定向到“file1”,那么在子级写入之后,子级应该更新什么?父级原
我对这些概念有点陌生。区分文件描述符和文件描述很重要,前者是进程在读写调用中用来标识文件的小整数,后者是内核中的一种结构。文件偏移量是文件描述的一部分。它生活在内核中 例如,让我们使用以下程序:
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
int main(void)
{
int fd;
fd = open("output", O_CREAT|O_TRUNC|O_WRONLY, 0666);
if(!fork()) {
/* child */
write(fd, "hello ", 6);
_exit(0);
} else {
/* parent */
int status;
wait(&status);
write(fd, "world\n", 6);
}
}
下面是发生的情况:
程序打开输出
文件,如果该文件不存在,则创建该文件;如果确实存在,则将其截断为零大小。内核创建一个文件描述(在Linux内核中,这是一个结构文件
),并将其与调用进程的文件描述符(该进程的文件描述符表中尚未使用的最低非负整数)相关联。文件描述符返回并分配给程序中的fd
。为了便于论证,假设fd
为3
程序执行fork()。新的子进程获取其父进程的文件描述符表的副本,但不复制文件描述。两个进程的文件表中的条目编号3指向相同的
struct file
父进程等待子进程写入。孩子的写入会导致文件中存储“hello world\n”
的前半部分,并将文件偏移量提前6。文件偏移量在结构文件中
子级退出,父级的wait()
完成,父级使用fd 3写入,fd 3仍然与子级的write()
更新了其文件偏移量的同一文件描述相关联。因此,消息的后半部分存储在第一部分之后,不会像父部分的文件偏移量为零时那样覆盖它,如果文件描述未共享,则会发生这种情况
最后,父级退出,内核看到结构文件不再使用并将其释放。在本书的同一部分中,有一个图表显示了打开文件时存在的三个表 用户filedescriptor表(流程表条目的一部分)、filetable和inode表(v节点表)。 现在,filedescriptor(文件描述符表的索引)条目指向一个文件表条目,该条目指向一个inode表条目。
现在文件偏移量(下一次读/写发生的位置)在文件表中。 假设您在父级中打开了一个文件,这意味着它有一个描述符,一个文件 表条目和索引节点引用。
现在,当您创建一个子文件时,会为该子文件复制文件描述符表。
因此,文件表条目中的引用计数(对于打开的描述符)增加,这意味着现在同一文件表条目有两个引用 此描述符现在在父级和子级中都可用,指向相同的文件表条目,因此共享偏移量。 现在有了这个背景,让我们看看你的问题
./hello
Parent ( )
{
open a file for writing, that is get the
descriptor( say fd);
close(1);//Closing stdout
dup(fd); //Now writing to stdout means writing to the file
close(fd)
//Create a child that is do a fork call.
ret = fork();
if ( 0 == ret )
{
write(1, "Child", strlen("Child");
exit ..
}
wait(); //Parent waits till child exit.
write(1, "Parent", strlen("Parent");
exit ..
}
Now I think the answer is clear-> by the system call that is by the OS.