首页 > 编程知识 正文

linux文件描述符的数据类型,java文件描述符

时间:2023-05-05 05:52:17 阅读:170662 作者:2323

博文说明【前言】:

本文以个人的口吻介绍了有关Linux文档描述符的知识。 目前【2017年7月4日】,掌握的技术水平有限,对知识的理解可能不充分或全面。 指出问题进行交流,如果在之后的工作和学习中发现正文内容与实际情况不一致的话,我想改善该博文的内容。

正文参考文献引用链接:

3、http://blog.csdn.net/kumu _ Linux/article/details/787770【好文】

正文:

在Linux上,我们知道所有的文件,实际上这个文件也分为几类。

主要内容(ls -l命令输出示例) :

-#普通文件

d#目录文件

l#链接文件

c #设备文件中的-字符类型设备文件

b #设备文件中的-块设备文件

n #设备文件中的-网络设备文件

1、普通文件

该文件是用户日常使用最多的文件,包括文本文件、shell脚本、二进制可执行文件和各种类型的数据文件。

此文件的属性通常由相关的APP应用程序(如touch、vim等)创建--rw--r---这些文件

2、目录文件

在Linux上,目录也是一个文件,目录内容可以是文件名和子目录名称,以及指向这些文件和子目录的指针

目录文件的属性通常是drwxr-xr-x,目录在Linux上是相对特殊的文件。

3、链接文件

链接文件类似于Windows的“快捷方式”

创建命令格式:

# ln/cp -s/-l /绝对路径/源文件名/绝对路径/新文件名

创建命令如下。

ln )要创建硬链接,inode编号必须在同一文件系统中相同,并且删除源文件时链接文件仍然存在) )。

ln -s (可以创建软链接或符号链接,并跨越文件系统。 inode编号不同,删除源文件将导致链接文件无效。)。

cp -l (要创建硬链接,inode编号必须在同一文件系统中相同,并且删除源文件时链接文件仍然存在) )。

cp -s (可以创建软链接或符号链接,并跨越文件系统。 inode编号不同,删除源文件将导致链接文件无效。)。

4、设备档案

有三种。 块设备文件,另一种类型为字符设备文件,与网络设备文件关系不大。

字符设备(无缓冲区,仅限顺序访问)、块设备(具有缓冲区,可随机访问)。

块设备文件是指读写数据,该数据是硬盘驱动器等以块为单位的设备。

字符设备主要是指网卡等串行端口的接口设备。

那么,基础概念的介绍结束了。 开始正题。 上方为个人书写,下方为引用。 引用篇幅超过50%,本文认为转载。

问题1 :什么是文件描述符?

1 .文件描述的概念

文件描述符是一个简单的整数,用于标识进程打开的每个文件和套接字。 第一个打开的文件为0,第二个为1,第三个文件为2。

文件描述符(file descriptor )是为有效管理内核打开的文件而创建的索引,是指向打开文件的非负整数(通常为小整数),所有执行输入和输出操作的系统调用都将文件描述符转换为程序刚启动时,0是标准输入,1是标准输出,2是标准错误。 现在去打开新文件,文件描述符为3。 POSIX标准要求每次打开包含套接字的文件时,都使用当前进程中可用的最小文件描述符代码。 因此,如果在网络通信中不注意,可能会发生串扰。 标准文件描述符的图示如下。

文件与打开的文件相对应的模型如下图所示。

2 .文件描述的限制

在编写文件操作和网络通信软件时,初学者通常可能会遇到“Too many open files”的问题。 这主要是因为文件描述符是系统的重要资源。 尽管文件描述符只需要系统内存就可以打开,但在实际实现中内核会进行相应的处理,通常最大打开文件数为系统内存的10%。 (按千字节计算) )这称为系统级限制)。

使用此命令可以显示在系统级别打开的最大文件数。 sysctl -a | grep fs.file-max

内核还使用缺省值处理单个进程的最大打开文件数,以防止某个进程占用所有文件资源。 这称为用户级别的限制。 缺省值通常为1024,可以使用ulimit -n命令显示。 在Web服务中,最常用的方法之一是通过更改系统缺省文件描述符的最大值来优化服务。

3 .文件说明符合打开的文件之间的关系

每个文件描述符对应于一个打开的文件,而不同的文件描述符也指向同一个文件。 可以在不同的进程中打开同一文件,也可以在同一进程中多次打开。 将维护每个进程的文件描述符表,其值从0开始。 因此

不同的进程中你会看到相同的文件描述符,这种情况下相同文件描述符有可能指向同一个文件,也有可能指向不同的文件。具体情况要具体分析,要理解具体其概况如何,需要查看由内核维护的3个数据结构。

1. 进程级的文件描述符表

2. 系统级的打开文件描述符表

3. 文件系统的i-node表

进程级的描述符表的每一条目记录了单个文件描述符的相关信息。

1. 控制文件描述符操作的一组标志。(目前,此类标志仅定义了一个,即close-on-exec标志)

2. 对打开文件句柄的引用

内核对所有打开的文件的文件维护有一个系统级的描述符表格(open file description table)。有时,也称之为打开文件表(open file table),并将表格中各条目称为打开文件句柄(open file handle)。一个打开文件句柄存储了与一个打开文件相关的全部信息,如下所示:

1. 当前文件偏移量(调用read()和write()时更新,或使用lseek()直接修改)

2. 打开文件时所使用的状态标识(即,open()的flags参数)

3. 文件访问模式(如调用open()时所设置的只读模式、只写模式或读写模式)

4. 与信号驱动相关的设置

5. 对该文件i-node对象的引用

6. 文件类型(例如:常规文件、套接字或FIFO)和访问权限

7. 一个指针,指向该文件所持有的锁列表

8. 文件的各种属性,包括文件大小以及与不同类型操作相关的时间戳

下图展示了文件描述符、打开的文件句柄以及i-node之间的关系,图中,两个进程拥有诸多打开的文件描述符。

在进程A中,文件描述符1和30都指向了同一个打开的文件句柄(标号23)。这可能是通过调用dup()、dup2()、fcntl()或者对同一个文件多次调用了open()函数而形成的。

进程A的文件描述符2和进程B的文件描述符2都指向了同一个打开的文件句柄(标号73)。这种情形可能是在调用fork()后出现的(即,进程A、B是父子进程关系),或者当某进程通过UNIX域套接字将一个打开的文件描述符传递给另一个进程时,也会发生。再者是不同的进程独自去调用open函数打开了同一个文件,此时进程内部的描述符正好分配到与其他进程打开该文件的描述符一样。

此外,进程A的描述符0和进程B的描述符3分别指向不同的打开文件句柄,但这些句柄均指向i-node表的相同条目(1976),换言之,指向同一个文件。发生这种情况是因为每个进程各自对同一个文件发起了open()调用。同一个进程两次打开同一个文件,也会发生类似情况。

4. 总结

1. 由于进程级文件描述符表的存在,不同的进程中会出现相同的文件描述符,它们可能指向同一个文件,也可能指向不同的文件

2. 两个不同的文件描述符,若指向同一个打开文件句柄,将共享同一文件偏移量。因此,如果通过其中一个文件描述符来修改文件偏移量(由调用read()、write()或lseek()所致),那么从另一个描述符中也会观察到变化,无论这两个文件描述符是否属于不同进程,还是同一个进程,情况都是如此。

3. 要获取和修改打开的文件标志(例如:O_APPEND、O_NONBLOCK和O_ASYNC),可执行fcntl()的F_GETFL和F_SETFL操作,其对作用域的约束与上一条颇为类似。

4. 文件描述符标志(即,close-on-exec)为进程和文件描述符所私有。对这一标志的修改将不会影响同一进程或不同进程中的其他文件描述符

文件描述符的具体应用

对于squid,因为squid 的工作方式,文件描述符的限制可能会极大的影响性能。当squid 用完所有的文件描述符后,它不能接收用户新的连接。也就是说,用完文件描述符导致拒绝服务。直到一部分当前请求完成,相应的文件和socket 被关闭,squid不能接收新请求。当squid发现文件描述符短缺时,它会发布警告。

对于Apache,当使用了很多虚拟主机,而每个主机又使用了不同的日志文件时,Apache可能会遭遇耗尽文件描述符(有时也称为file handles)的困境。 Apache使用的文件描述符总数如下:每个不同的错误日志文件一个、 每个其他日志文件指令一个、再加10~20个作为内部使用。Unix操作系统限制了每个进程可以使用的文件描述符数量。典型上限是64个,但可以进行扩充,直至到达一个很大的硬限制为止(a large hard-limit)。

linux下最大文件描述符的限制有两个方面,一个是用户级的限制,另外一个则是系统级限制。

以下是查看Linux文件描述符的三种方式:

系统级限制:

[root@localhost ~]# sysctl -a | grep -i file-max --color

fs.file-max = 392036

[root@localhost ~]# cat /proc/sys/fs/file-max

392036

用户级限制:

[root@localhost ~]# ulimit -n

1024

[root@localhost ~]#

系统级限制:sysctl命令和proc文件系统中查看到的数值是一样的,这属于系统级限制,它是限制所有用户打开文件描述符的总和

用户级限制:ulimit命令看到的是用户级的最大文件描述符限制,也就是说每一个用户登录后执行的程序占用文件描述符的总数不能超过这个限制

如何修改文件描述符的值?

1、修改用户级限制

[root@localhost ~]# ulimit-SHn 10240

[root@localhost ~]# ulimit  -n

10240

[root@localhost ~]#

以上的修改只对当前会话起作用,是临时性的,如果需要永久修改,则要修改如下:

[root@localhost ~]# grep -vE'^$|^#' /etc/security/limits.conf

*                hard nofile                  4096

[root@localhost ~]#

//默认配置文件中只有hard选项,soft 指的是当前系统生效的设置值,hard 表明系统中所能设定的最大值

[root@localhost ~]# grep -vE'^$|^#' /etc/security/limits.conf

*      hard         nofile       10240

*      soft         nofile      10240

[root@localhost ~]#

// soft<=hard soft的限制不能比hard限制高

2、修改系统限制

[root@localhost ~]# sysctl -wfs.file-max=400000

fs.file-max = 400000

[root@localhost ~]# echo350000 > /proc/sys/fs/file-max  //重启后失效

[root@localhost ~]# cat /proc/sys/fs/file-max

350000

[root@localhost ~]#

//以上是临时修改文件描述符

//永久修改把fs.file-max=400000添加到/etc/sysctl.conf中,使用sysctl -p即可

下面是摘自kernel document中关于file-max和file-nr参数的说明

file-max & file-nr:

The kernel allocates file handles dynamically, but as yet it doesn't free them again.

内核可以动态的分配文件句柄,但到目前为止是不会释放它们的

The value in file-max denotes the maximum number of file handles that the Linux kernel will allocate. When you get lots of error messages about running out of file handles, you might want to increase this limit.

file-max的值是linux内核可以分配的最大文件句柄数。如果你看到了很多关于打开文件数已经达到了最大值的错误信息,你可以试着增加该值的限制

Historically, the three values in file-nr denoted the number of allocated file handles, the number of allocated but unused file handles, and the maximum number of file handles. Linux 2.6 always reports 0 as the number of free file handles -- this is not an error, it just means that the number of allocated file handles exactly matches the number of used file handles.

在kernel 2.6之前的版本中,file-nr 中的值由三部分组成,分别为:1.已经分配的文件句柄数,2.已经分配单没有使用的文件句柄数,3.最大文件句柄数。但在kernel 2.6版本中第二项的值总为0,这并不是一个错误,它实际上意味着已经分配的文件句柄无一浪费的都已经被使用了

结尾:

感谢阅读,祝有收获的一天,谢谢!

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。