[APUE]文件描述符

  内核(kernel)利用文件描述符(file descriptor)用以标识一个特定进程正在访问的文件,它是一个索引值。文件描述符是一个非负整数。当内核打开一个现有文件或创建一个新文件时,内核都会返回一个文件描述符。读写文件时,用open或creat返回的文件标示符标识该文件,将其作为参数传递给read或write。

  按惯例,每当运行一个新程序时,所有shell都默认为其打开3个文件描述符:标准输入(standard input[0]),标准输出(standard output[1])以及标准错误(standard error[2])。其实如果你分析了内核的源码后会发现,文件描述符,其实是当前程序打开文件结构数组的下标,当一个程序启动时,系统默认的让他打开了三个文件,就是标准输入,标准输出,标准错误输出,它们的在打开文件结构数据的下标就是0,1,2。因此,如果我的程序再打开一个新的文件,那么应该这个下标(文件描述符)就应该是3,下面我们证明下。

#include <stdio.h>

#include <fcntl.h>

int main(void)

{

        int fd;

        fd = open("/tmp/tmp.txt", O_RDONLY);

        printf("fd:%d/n", fd);

        return 0;

}

  文件描述符的范围是0—OPEN_MAX 。早期的UNIX版本采用的上限值是1 9 (允许每个进程打开2 0个文件),现在很多系统则将其增加至256。这个好理解,一个程序不可能无休止的打开文件,有个限制,这个限制每个系统可能都不太一样,要是想查看你自己系统的最大打开文件数,也就是文件描述符范围,也用grep去找一个OPEN_MAX这个字符串。

  进程获取文件描述符最常见的方法是通过本机子例程open或create获取或者通过从父进程继承。后一种方法允许子进程同样能够访问由父进程使用的文件。文件描述符对于每个进程一般是唯一的。当用fork子例程创建某个子进程时,该子进程会获得其父进程所有文件描述符的副本,这些文件描述符在执行fork时打开。在由fcntl、dup和dup2子例程复制或拷贝某个进程时,会发生同样的复制过程。对于每个进程,操作系统内核在u_block结构中维护文件描述符表,所有的文件描述符都在该表中建立索引。
  优点:
  1、基于文件描述符的I/O操作兼容POSIX标准。
  2、在UNIX、Linux的系统调用中,大量的系统调用都是依赖于文件描述符。
  3、在Linux系列的操作系统上,由于Linux的设计思想便是把一切设备都视作文件。因此,文件描述符为在该系列平台上进行设备相关的编程实际上提供了一个统一的方法。
  缺点:
  1、在非UNIX/Linux操作系统上(如Windows NT),无法基于这一概念进行编程。
  2、由于文件描述符在形式上不过是个整数,当代码量增大时,会使编程者难以分清哪些整数意味着数据,哪些意味着文件描述符。因此,完成的代码可读性也就会变得很差。
 
引用文献:
1、http://blog.csdn.net/linuxmichael/article/details/5156790
2、百度百科
原文地址:https://www.cnblogs.com/kona/p/4647405.html