linux 文件描述符 最大值,Linux最大文件句柄(文件描述符)限制和修改

转自:http://jameswxx.iteye.com/blog/2096461

写这个文章是为了以正视听,网上的文章人云亦云到简直令人发指。到底最大文件数被什么限制了?too many open files错误到底可以通过什么参数控制?网上的很多文章说的大致步骤是没有错的,大致如下:

shell级限制

通过ulimit -n修改,如执行命令ulimit -n 1000,则表示将当前shell的当前用户所有进程能打开的最大文件数量设置为1000.

用户级限制

ulimit -n是设置当前shell的当前用户所有进程能打开的最大文件数量,但是一个用户可能会同时通过多个shell连接到系统,所以还有一个针对用户的限制,通过修改 /etc/security/limits.conf实现,例如,往limits.conf输入以下内容:

root soft nofile 65535

root hard nofile 65535

* soft nofile 65535

* hard nofile 65535

~

soft nofile表示软限制,hard nofile表示硬限制,软限制要小于等于硬限制。上面两行语句表示,root用户的软限制为1000,硬限制为1200,即表示root用户能打开的最大文件数量为1000,不管它开启多少个shell。

系统级限制

修改cat /proc/sys/fs/file-max

但是呢,有很多很重要的细节,有很多错误的描述,一塌糊涂,因此特的在这里做一个说明。

一  ulimit -n

网上很多人说,ulimit -n限制用户单个进程的问价打开最大数量。严格来说,这个说法其实是错误的。看看ulimit官方描述:

Provides control over the resources available to the shell and to processes started by  it,  on  systems that allow such control. The -H and -S options specify that the hard or soft limit is set for the given resource. A hard limit cannot be increased once it is set; a soft limit may  be  increased  up  to  the value of the hard limit. If neither -H nor -S is specified, both the soft and hard limits are set. The value of limit can be a number in the unit specified for the resource or one of the special values hard, soft,  or  unlimited,  which  stand  for  the  current hard limit, the current soft limit, and no limit,  respectively.

If limit is omitted, the current value of the soft limit  of  the  resource  is  printed,  unless  the  -H  option is given.  When more than one resource is specified, the limit name and unit are  printed before the value.

人家从来就没说过是限制用户的单个进程的最大文件打开数量,看看红色部分,是限制当前shell以及该shell启动的进程打开的文件数量。为什么会给人限制单个线程的最大文件数量的错觉,因为很多情况下,在一个shell环境里,虽然可能会有多个进程,但是非常耗费文件句柄的进程不会很多,只是其中某个进程非常耗费文件句柄,比如服务器上运行着一个tomcat,那么就是java进程要占用大多数文件句柄。此时ulimit设置的最大文件数和java进程耗费的最大文件数基本是对应的,所以会给人这样的一个错觉。

还有,很多文章称ulimit -n 只允许设置得越来越小,比如先执行了ulimit -n 1000,在执行ulimit -n 1001,就会报"cannot modify limit: Operation not permitted"错误。这个其实也是不准确的说法。首先要搞清楚,任何用户都可以执行ulimit,但root用户和非root用户是非常不一样的。

非root用户只能越设置越小,不能越设置越大

我在机器上以非root先执行:

[wxx@br162 etc]$ ulimit -n 900

[wxx@br162 etc]$

执行成功,再增大:

[wxx@br162 etc]$ ulimit -n 901

-bash: ulimit: open files: cannot modify limit: Operation not permitted

[wxx@br162 etc]$

增加失败,如果减少则是OK的:

[wxx@br162 etc]$ ulimit -n 899

[wxx@br162 etc]$

如果再增加到900是不行的:

[wxx@br162 etc]$ ulimit -n 900

-bash: ulimit: open files: cannot modify limit: Operation not permitted

[wxx@br162 etc]$

root用户不受限制

首先切换到root:

[wxx@br162 etc]$ sudo su -

[root@br162 ~]#

查看下当前限制:

[root@br162 ~]# ulimit -n

1000000

[root@br162 ~]#

增大:

[root@br162 ~]# ulimit -n 1000001

[root@br162 ~]#

可以成功增大,再减小:

[root@br162 ~]# ulimit -n 999999

[root@br162 ~]#

减小也是成功的,再增大:

[root@br162 ~]# ulimit -n 1000002

[root@br162 ~]#

也是ok的,可见root是不受限制的。

ulimit里的最大文件打开数量的默认值

如果在limits.conf里没有设置,则默认值是1024,如果limits.con有设置,则默认值以limits.conf为准。例如我换了一台机器,登录进去,ulimit -n显示如下:

[root@zk203 ~]# ulimit -n

2000

这是因为我的limits.conf里的文件打开数是2000,如下:

[root@zk203 ~]# cat /etc/security/limits.conf

root soft nofile 2000

root hard nofile 2001

如果limits.conf里不做任何限制,则重新登录进来后,ulimit -n显示为1024。

[root@zk203 ~]# ulimit -n

1024

ulimit修改后生效周期

修改后立即生效,重新登录进来后失效,因为被重置为limits.conf里的设定值

二  /etc/security/limits.conf

网上还有缪传,ulimit -n设定的值不能超过limits.conf里设定的文件打开数(即soft nofile)

好吧,其实这要分两种情况,root用户是可以超过的,比如当前limits.conf设定如下:

root soft nofile 2000

root hard nofile 2001

但是我用root将最大文件数设定到5000是成功的:

[root@zk203 ~]# ulimit -n 5000

[root@zk203 ~]# ulimit -n

5000

[root@zk203 ~]#

但是非root用户是不能超出limits.conf的设定,我切换到wxx,执行命令如下:

[wxx@zk203 ~]# ulimit -n 5000

-bash: ulimit: open files: cannot modify limit: Operation not permitted

[wxx@zk203 etc]$

所以网上的说法是错误的,即使非root用户的最大文件数设置不能超过limits.conf的设置,这也只是一个表象,实际上是因为,每个用户登录进来,ulimit -n的默认值是limits.conf的 soft nofile指定的,但是对于非root用户,ulimit -n只能越来越小,不能越来越大,其实这个才是真正的原因,但是结果是一样的。

修改了limits.conf需要重启系统?

这个说法非常搞笑,修改了limits.conf,重新登录进来就生效了。在机器上试试就知道了,好多人真的很懒,宁愿到处问也不愿意花一分钟时间实际操作一下。

三  /proc/sys/fs/file-max

网上说,ulimit -n 和limits.conf里最大文件数设定不能超过/proc/sys/fs/file-max的值,这也是搞笑了,/proc/sys/fs/file-max是系统给出的建议值,系统会计算资源给出一个和合理值,一般跟内存有关系,内存越大,改值越大,但是仅仅是一个建议值,limits.conf的设定完全可以超过/proc/sys/fs/file-max。

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

1610495

我将limits.conf里文件最大数量设定为1610496,保存后,打印出来:

[root@zk203 ~]# cat /etc/security/limits.conf

root soft nofile1610496

root hard nofile1610496

四  总结一下

/proc/sys/fs/file-max限制不了/etc/security/limits.conf

只有root用户才有权限修改/etc/security/limits.conf

对于非root用户, /etc/security/limits.conf会限制ulimit -n,但是限制不了root用户

对于非root用户,ulimit -n只能越设置越小,root用户则无限制

任何用户对ulimit -n的修改只在当前环境有效,退出后失效,重新登录新来后,ulimit -n由limits.conf决定

如果limits.conf没有做设定,则默认值是1024

当前环境的用户所有进程能打开的最大问价数量由ulimit -n决定

<think>好的,我现在需要仔细分析用户的问题,并给出关于inode文件描述符的详细解释。用户之前已经提问过类似的问题,现在再次询问,可能希望得到更深入或更清晰的解释。首先,我需要回顾之前的回答相关引用,确保信息的一致性,同时补充新的内容。用户的问题集中在inode文件描述符的区别及联系。根据之前的引用,inode是磁盘上的索引节点,存储文件的元数据;而文件描述符是进程打开文件时的句柄,指向内核中的structfile结构。我需要明确两者的定义、作用、生命周期以及它们之间的关系。接下来,用户可能希望了解它们如何协同工作,比如当打开文件时,内核如何通过路径找到inode,创建structfile,并分配文件描述符。这部分需要结合具体的系统调用流程,比如open()read(),来说明它们的联系。此外,需要提到硬链接软链接对inode的影响,以及不同进程访问同一文件文件描述符的独立性。还要注意数学公式的正确使用,比如最大文件数的计算文件描述符限制。这些公式需要用LaTeX格式正确呈现,并确保符合用户的要求,即行内公式用$...$,独立公式用$$...$$。另外,用户提供的引用中有几个关键点:引用1说明fdstructfile的关系;引用2指出inode对应磁盘文件,structfile对应打开的文件实例;引用3解释inode的作用;引用4提到文件描述符是索引值。需要将这些引用内容自然地融入回答中,并在适当的位置添加引用标记。最后,生成的相关问题需要与主题紧密相关,比如查看文件描述符的命令、泄漏影响、inode显示方法、硬链接计数变化以及读写位置隔离。这些问题应帮助用户进一步理解或排查相关问题。 检查回答结构是否清晰,是否分点说明区别联系,是否有代码示例或流程图辅助说明。确保没有使用Markdown格式,语言口语化,逻辑连贯,覆盖所有关键点。</think>### 索引节点(inode)与文件描述符(file descriptor)的深度解析 #### 一、核心概念解析 1. **索引节点(inode)** - **定义**:inode 是文件系统管理文件的核心数据结构,存储文件的**元数据**(如权限、大小、时间戳、数据块指针等),但不包含文件名[^3][^4]。 - **存储位置**:持久化在磁盘的 inode 表中,文件系统初始化时预先分配固定数量的 inode[^2][^3]。 - **唯一性**:同一文件系统内每个 inode 编号唯一,跨文件系统可能重复(如不同磁盘分区)。 2. **文件描述符(file descriptor, fd)** - **定义**:fd 是进程访问文件的**临时句柄**,本质是进程文件描述符表的索引值(非负整数)[^4]。 - **存储位置**:内存中进程的`struct files_struct`结构内,进程退出后自动释放[^1][^2]。 - **唯一性**:同一进程内唯一,不同进程可能拥有相同数值的 fd(指向不同文件)。 #### 二、关键区别对比 | 维度 | inode | 文件描述符 (fd) | |--------------------|-------------------------------------------|----------------------------------------| | **作用目标** | 文件本身(如数据块位置、权限)[^3] | 进程与文件的交互状态(如读写位置、打开模式)[^1] | | **生命周期** | 文件存在即存在,删除后可能被回收 | 进程打开文件时创建,关闭后立即销毁 | | **跨进程共享** | 多个进程可访问同一文件的 inode | 不同进程的 fd 相互独立(即使指向同一文件) | | **数据结构** | `struct inode`(磁盘元数据) | `struct file`(内存中的操作状态)[^2] | #### 三、协作关系与操作流程 当进程调用`open("file.txt")`时: 1. **路径解析**:内核通过路径逐层查找目录项(dentry),最终定位目标文件的 inode。 2. **创建文件对象**:生成`struct file`对象,关联 inode 并记录读写位置(`f_pos`)、打开模式(`f_flags`)[^2]。 3. **分配 fd**:在进程的 fd 表中找到最小未使用索引(如 fd=3),将其指向`struct file`。 ```c // 内核数据结构示例 struct file { struct inode *f_inode; // 指向文件 inode loff_t f_pos; // 当前读写偏移量 atomic_long_t f_count; // 引用计数 }; ``` #### 四、数学关系建模 1. **文件系统容量限制**: $$ \text{最大文件数} = \min\left(\frac{\text{磁盘总空间}}{\text{平均文件大小}}, \text{inode 总数}\right) $$ 若 inode 耗尽,即使磁盘有剩余空间也无法创建新文件[^3]。 2. **进程文件描述符限制**: $$ \text{可打开 fd 数} = \min\left(\text{系统级限制 (/proc/sys/fs/file-max)}, \text{用户级限制 (ulimit -n)}\right) $$ #### 五、典型场景分析 - **硬链接创建**:硬链接与原始文件共享同一 inode,inode 的引用计数(`i_count`)加 1[^3]。 - **多进程写文件**:每个进程的 fd 独立维护`f_pos`,写操作可能相互覆盖(除非使用`O_APPEND`模式)[^2]。 - **文件删除**:删除文件时目录项被清除,但 inode 可能仍被进程通过 fd 持有(直到所有 fd 关闭才释放)[^2]。 --- ### 相关问题 1. 如何通过`ls -i`命令查看文件的 inode 编号? 2. 文件描述符泄漏会导致哪些系统问题? 3. 为什么不同进程对同一文件的读写位置可以独立控制? 4. 硬链接与软链接在 inode 引用上有何区别? 5. 如何修改 Linux 系统的最大文件描述符限制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值