首页 > 系统相关 >Linux中的fd

Linux中的fd

时间:2022-10-07 19:45:23浏览次数:75  
标签:文件 vim 描述符 fd Linux 进程 打开

Linux中的fd

起子

​ 如果说系统学Linux,我其实没有这个经历,你问我xx环境在Linux内核某个发行版怎么配置,那我可能可以告诉你,但是你要问我很多kernel相关的内容,那我就不懂了。在之前的一篇美团面经里涉及到select、poll、epoll这三个方法,那这三个方法肯定就和fd离不开关系,但是当时不懂这个是什么,于是乎就先跑去把fd学了一下,那理所应当的就要写一个随笔记录一下了。

文件描述符的简单概念

​ 我们可以把文件描述符当作是一个非负整数,本质上是一个索引值,在Linux中我们都知道,一切都可以看作是文件,细分有普通文件、目录文件、链接文件、设备文件。OS里我们都学过文件管理,如果我们每次想要操作A文件,都要去找哪个文件名字和A一致,就十分的浪费时间,所以我们有了index(索引)这个概念。Linux内核中规定每一个文件对应一个索引

​ 上述的这些索引就是文件描述符,通常是一个非负整数,并且值较小,文件描述符被拿来指代打开的文件,所有执行I/O操作的系统调用都通过文件描述符来实现。按照规定,0是stdin(标准输入),1是stdout(标准输出),2是标准错误(stderr)。这就意味着我们打开一个新文件,文件描述符紧接着会是3,再打开一个就是4……以此类推

​ 同样的,还会有一张表格存储这些文件描述符(不解释原因了,这个OS都共通的),内容为文件描述符(一个小整数)与其对应打开的文件的指针。

文件描述符的详细内容

​ 实际上Linux内核为文件描述符维护了3个数据结构:

  • 进程级别的文件描述符表
  • 系统级别的打开文件描述符表
  • 文件系统的i-node表

​ 当一个进程启动后,内核会为其创建一个PCB,PCB内部有一张文件描述符表,记录着当前进程所有可用的文件描述符,也就是当前进程所有打开的文件。进程级别的文件描述符表每一条都记录着单个进程所使用的文件描述符相关信息。需要注意的是,进程之间是相互独立的(这个也不解释了吧,大家都清楚),所以A进程使用了文件描述符3,那么另一个进程也可以使用文件描述符3。另外的两张表,系统级别的打开文件描述符表,存储了每个打开文件的打开文件句柄。一个打开文件句柄存储了与一个打开文件相关的全部信息。

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

  • 当前文件偏移量(使用read()和write()时更新,或使用lseek()直接修改)
  • 打开文件的标识(open()的flags参数)
  • 文件访问模式(是只读、只写或者读写等模式)
  • 信号驱动相关设置
  • i-node表指针

文件系统的i-node表

  • 文件类型(常规文件、套接字)和访问权限
  • 指向该文件所持有的锁列表
  • 文件的各种属性,如文件大小、不同类型操作相关的时间戳

f5U8N.png

  • 在进程A中,文件描述符1和20都指向了同一个打开文件表项,出现这种情况的原因可能是通过调用dup(),dup2(),fcntl()或者对同一个文件多次调用了open()函数所造成的
  • 进程A的文件描述符2和进程B的文件描述符2指向了同一个文件,出现这种情况的原因可能是通过调用fork()函数后出现(即A和B进程是父子关系),或者是不同的进程独自调用open()函数打开了同一个文件
  • 进程A的描述符0和进程B的描述符3虽然指向了不同的打开文件表项,但是却指向了同一个i-node表项;出现这种情况的原因可能是两个进程各自对同一个文件调用open(),或者是同一个进程两次打开同一个文件

Linux实际举例

​ 我们找一个安装有基于Linux内核发行版系统的机器,然后在终端输入使用vim foobar随便打开一个文件

ffjBB.png

​ 之后再开一个连接(终端),然后输入pidof vim或者vim的pid,紧接着用ll /proc/$pid/fd来查看vim进程所使用的文件描述符列表

ffGdm.png

​ 如果之前没看过我的那篇vim工作原理,可能就会对除了前三个之外的文件描述符产生疑惑,那3和4这两个文件描述符是redis自身的原因,我们不讨论,只讨论因为vim所导致的编号为6的文件描述符。

​ /dev/pts是远程登录(telnet、ssh等)后创建的终端设备文件所在的目录。0是标准输入,1是标准输出,2是标准错误,这些统统指向标号为0的终端控制台。而vim打开的redis.conf,按道理来说应该是顺接着标号为4的套接字,紧接着用5作为文件描述符,但图中却是6。

​ 这个原因同样在vim工作原理的博客中讲到,原因是因为vim会先打开源文件并且拷贝一份,之后关闭源文件再打开副本进行修改,当副本修改完选择保存,就用副本重命名覆盖原文件。所以打开源文件其实就是文件描述符5,之后文件描述符5被释放,查看的时候就剩下了.swp副本文件。

Linux中关于文件描述符的系统配置

(1)系统级别的限制

​ 从理论上来说,计算机有多少内存,我们可以一直开文件,也就是一直能有文件描述符,但是实际上我们肯定实现不了这点,所以内核会进行相应的处理。一般来说最大打开文件数是系统内存的十分之一,这个配置文件在/proc/sys/fs/file-max中配置,除了查看这个文件内容外,还可以使用sysctl -a | gerp fs.file-max来进行查看

​ 临时更改系统级别限制大小的方式为:使用命令sysctl -w fs.file-max-xxx来临时更改

​ 永久更改的方式就需要编辑/etc/sysctl.conf文件,在文件的内容后添加fs.file-max=xxx,保存退出后使用sysctl -p使命令生效

(2)用户级别限制

​ 内核也会对单个进程所能打开的最大文件数进行限制,也就是用户级别的限制,32位系统一般默认为1024,而64位系统一般默认为65535,我们可以使用ulimit -n命令查看

​ 临时更改用户级别限制大小方式为:使用命令ulimit -SHn xxxx进行修改

​ 永久更改用户级别限制大小的方式为:vim编辑/etc/security/limits.conf文件,将其中的hard nofile xxxxsoft nofile xxxx

结语

​ 到这里就讲完我目前的水平对文件描述符的理解了,当然实际上肯定是有差错并且深度还远远不够的,还是和之前的文章一样,如果之后学习到了更加正确并且深层次的内容,同样会更新在这里,或者是开一篇新帖。

​ 感谢阅读。

标签:文件,vim,描述符,fd,Linux,进程,打开
From: https://www.cnblogs.com/appletree24/p/16760512.html

相关文章

  • Linux实习报告
     沈阳航空航天大学 Linux系统操作实习报告  院(系):计算机学院专   业:计算机科学与技术班   级:1434010105学   号:143401010516姓   名:徐建磊......
  • Linux 生成复杂密码并且检查密码强度
    在本教程中,我们将讨论如何生成复杂密码并且检查密码强度。生成复杂的密码强密码应由字母、数字和符号的混合组成。第二个要求是不要使用已知单词、出生日期或姓名,因为很容易......
  • Shell及Linux常见易错题目题库-Shell/Linux-选择、简答、判断、编程
    1、以下不合法的shell头是(不合法指运行会报错)(   )A.#!/bin/bashB.#-/bin/bashC.!#/bin/bash答案:C 2、if[$2-a$2="test"]中-a是什么意思(  )A.大于B.减C.......
  • Linux命令系列之ls——原来最简单的ls这么复杂
    Linux命令系列之ls——原来最简单的ls这么复杂ls命令应该是我们最常用的命令之一了,但是我们可能容易忽略那些看起来最简单的东西。简介ls命令的使用格式如下ls[选项]......
  • linux创建新用户后,只显示$符号的修改办法
    背景创建了一个用户useraddxpw创建完之后,切换到用户xpw,发现,窗口只显示$了 解决方案切换到rootvi/etc/passwd找到xpw这一行,把bin/sh改成bin/bash保存......
  • Linux 常用命令 CentOS
    网络相关ipaddr//查看网络及网卡编号systemctlrestartnetwork//重启网络vi/etc/sysconfig/network-scripts/ifcfg-网卡编号//修改网络相关配置ifconfig//查看......
  • linux常用命令总结
    1.查询当前目录总大小du-sh2.批量解压缩ls*.tar.gz|xargs-n1tarxzvf3.解压缩tar-zxv-ffilename.tar.gz4.查看内存free-h5.远程拷贝文件scp......
  • Linux 用户操作指令
    创建用户默认情况下创建一个用户账号,会创建一个家目录和一个用户邮箱(在/var/spool/mail目录以用户名命名)[root@localhost~]#useradd<username>useradd参数说明......
  • 【Linux】基于Ubuntu搭建Apache + Tomcat+ Memcached集群
    这又是一篇来自2015年的文章,当时因为要解决一个项目Session共享问题,需要搭建与生产环境一样的环境进行验证。同时,根据领导要求需要将生产环境做成水平扩展集群,因此也在本环......
  • jenkins linux服务器使用ssh实现免密登陆
    需求Jenkins部署的时候需要登陆到部署机执行shell脚本,然后采用ssh免密登陆。具体步骤(1)、客户端首先向服务器发送要对其进行身份验证的密钥对的用户名。(2)、服务器检查客......