一、函数声明
#include <unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);
二、解释
dup将复制oldfd文件描述符,返回新的描述符
dup2将复制oldfd到指定的newfd上,如果newfd有已经存在的描述符则关闭(如果oldfd==newfd就不会关闭)
三、实例
#include <stdio.h>
#include <unistd.h>
#define FD_STDOUT 1
int
main(int argc, char **args)
{
int fd_stdout = dup(FD_STDOUT);
int fd_stdout_e = 100;
dup2(FD_STDOUT, fd_stdout_e);
write(fd_stdout, "100: hotice0\n", sizeof("100: hotice0\n"));
close(fd_stdout_e);
close(1);
printf("kk\n");
write(fd_stdout, "hotice0\n", sizeof("hotice0\n"));
close(fd_stdout);
return 0;
}
//运行结果
hotice0@ubuntu:~/Documents/Unix_Program$ ./file-io/dup_dup2
100: hotice0
hotice0
该处的代码有几处值得注意的:
1.发现printf应该打印的kk并没有打印出来,因为我们close掉了1文件描述符。这个是stdout所对应的文件描述符。stdin是0。
2.我们发现使用dup,从1复制的文件描述符,在1被关闭后,仍然可以正常的使用,说明复制后的文件描述符与原文件描述符完全独立。(但是会使用同样的i,v文件节点)。
那么i,v文件节点应该会有引用计数,来标识有多少个文件描述符的文件表项(不懂看下面示意图),引用该i,v节点。当引用为0时,会释放i,v节点。
备注:linux下,通常只有i节点,没有v节点。
突发奇想:如果你需要调用一个命令对某个文件不停的操作。而这个文件只会被这个命令引用时。系统可能会不停的生成和释放该i节点。如果,你通过一个进程一直打开该文件,是不是会使得该文件的i节点一直存在。从而减少了该节点的重复生成和释放。
此处附上,从"Unix高级环境编程"引用的文件描述符,文件表项,i,v节点的关系示意图。

本文介绍了Linux系统中的dup和dup2函数,详细解析了它们的功能:dup复制文件描述符并返回新描述符,dup2则将一个文件描述符复制到指定的另一个描述符上,同时关闭原有描述符。通过实例展示了这两个函数的使用,并讨论了文件描述符、i节点和v节点的关系,以及在特定场景下如何减少i节点的生成和释放。
329

被折叠的 条评论
为什么被折叠?



