注册

Linux报 “too many open files in process” 异常的原因以及解决办法

Linux系统中,每个进程都有一个打开文件描述符限制,当进程打开文件数量超过这个限制时,就会报错 "too many open files in process"。这个限制的默认值通常较小,相对于实际需要打开的文件数来说很容易达到上限。

解决这个问题有两种方法,下面分别介绍。

方法一:调整进程打开文件描述符限制

查询当前进程的文件描述符限制

可以使用 ulimit 命令来查询当前进程的打开文件描述符限制。例如,输入下面的命令:

ulimit -n

会输出当前进程的文件描述符限制数目。

修改文件描述符限制

可以使用 ulimit 命令来修改文件描述符限制。例如,设置当前进程的打开文件描述符数目限制为 65536,可以输入下面的命令:

ulimit -n 65536

该命令会将当前进程的打开文件描述符数目限制修改为 65536,可以通过 ulimit -n 命令进行验证。

修改系统范围内的文件描述符限制

如果需要修改系统范围内的文件描述符限制,可以修改 /etc/security/limits.conf 文件中的相应项。例如,可以在该文件中加入以下内容:

*               soft    nofile          65536
*               hard    nofile          65536

这个意思是将所有用户的软限制和硬限制都设置为 65536,即所有用户的进程最多可以同时打开 65536 个文件描述符。

示例

假设我们有一个 Python 脚本,需要打开很多文件。但是,由于文件描述符限制的原因,程序在运行的过程中报错 "too many open files in process"。我们可以使用方法一来解决这个问题。

首先,使用 ulimit -n 命令查询当前进程的文件描述符限制:

$ ulimit -n
1024

当前进程的最大文件描述符数目为 1024。

然后,我们可以先尝试将该限制增加到 4096:

$ ulimit -n 4096

再运行 Python 脚本,如果还是出现 "too many open files in process" 的错误,可以将限制增加到更大的值。

方法二:关闭不必要的文件描述符

在程序运行过程中,如果有一些文件描述符已经不再需要,可以通过关闭这些文件描述符来释放资源。可以使用 close() 函数来关闭文件描述符。

查看进程打开的文件列表

可以使用 lsof 命令来查看进程打开的文件列表。例如,输入下面的命令:

lsof -p 

其中, 是进程的 ID。该命令会输出进程打开的所有文件描述符及其状态等信息。

关闭文件描述符

在程序中使用 close() 函数来关闭文件描述符。例如,在 Python 中,使用 os 模块的 close() 函数关闭文件描述符。例如,下面的代码演示了如何打开一个文件并在使用完成后关闭该文件:

import os

fd = os.open('/path/to/file', os.O_RDONLY)
# 在这里对文件进行操作
os.close(fd)

示例

假设我们有一个 Python 脚本,需要递归遍历一个目录下的所有文件并操作这些文件。在程序运行的过程中,由于没有及时关闭文件描述符,程序报错了 "too many open files in process"。我们可以使用方法二来解决这个问题。

首先,我们可以使用 lsof 命令来查看进程打开的所有文件描述符,例如:

$ lsof -p 

其中, 为进程的 ID。

然后,我们需要在程序中添加代码来关闭不再需要的文件描述符。例如,在 Python 中,可以使用类似下面的代码来打开文件并关闭文件:

import os

def process_file(filename):
    with os.open(filename, os.O_RDONLY) as fd:
        # 在这里对文件进行操作
        pass

def process_directory(dirname):
    for filename in os.listdir(dirname):
        filename = os.path.join(dirname, filename)
        if os.path.isfile(filename):
            process_file(filename)
        elif os.path.isdir(filename):
            process_directory(filename)