【问题标题】:OSError: [Errno 24] Too many open files; in python; difficult to debugOSError: [Errno 24] 打开的文件太多;在蟒蛇中;难以调试
【发布时间】:2021-10-17 09:30:53
【问题描述】:

我正在运行的代码有时会在数小时后,有时数分钟后因错误而失败

OSError: [Errno 24] Too many open files

我在调试这个时遇到了很大的麻烦。错误本身总是由下面代码sn-p中的标记行触发

try:
    with open(filename, 'rb') as f:
        contents = f.read()       <----- error triggered here
except OSError as e:
    print("e = ", e)
    raise
else:
    # other stuff happens

但是,我在这部分代码中看不到任何问题(对吗?)所以我猜代码的其他部分没有正确关闭文件。但是,虽然我确实打开了很多文件,但我总是用'with'语句打开它们,我的理解是即使发生错误,文件也会被关闭(对吗?)。所以我的代码的另一部分看起来像这样

    try:
        with tarfile.open(filename + '.tar') as tar:
            tar.extractall(path=target_folder)
    except tarfile.ReadError as e:
        print("e = ", e)
    except OSError as e:
        print("e = ", e)
    else:
        # If everything worked, we are done
        return

上面的代码确实经常遇到 ReadError,但即使发生这种情况,文件也应该关闭,对吧?所以我只是不明白我怎么会遇到太多打开的文件?抱歉,这对您来说无法重现,因为我无法调试它,我只是在这里寻找一些提示,因为我迷路了。任何帮助表示赞赏...

编辑:我在 macbook 上。这是 ulimit -a 的输出

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 256
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1418
virtual memory          (kbytes, -v) unlimited

根据@sj95126 的建议,我将有关 tar 文件的代码更改为确保文件已关闭的代码

try:
    tar = tarfile.open(filename + '.tar')
    tar.extractall(path=target_folder)
except tarfile.ReadError as e:
    print("tarfile.ReadError e = ", e)
except OSError as e:
    print("e = ", e)
else:
    # If everything worked, we are done
    return
finally:
    print("close tar file")
    try:
        tar.close()
    except:
        print("file already closed")

但它并没有解决问题。

【问题讨论】:

  • 如果你使用的是linux,请告诉我file locks在cmd中使用ulimit -a的值。
  • 通常你是对的,with 应该导致文件被关闭;但是,管理对象中始终存在错误的可能性。 tarfile 对象必须关闭文件,with 不会到达 file 对象并执行此操作。只是为了测试,尝试在try 中添加finally 子句并显式调用tar.close(),看看是否有帮助。
  • 感谢所有 cmets。 @alexzander 我在上面添加了 ulimit -a。
  • @sj95126 这是一个很好的观点。我会测试你的建议。
  • @Carcigenicate 还有更多我使用文件的情况,但它们具有相同的语法并且它们是按顺序使用的,而不是并行使用的。我很确定这一定是我的代码,因为即使我停止了所有其他程序,我也会收到此错误。

标签: python file-handling with-statement


【解决方案1】:

unix/linux 系统上,有一个命令可以使用ulimit -a 检查file locksopen files 的总数限制。在@carl 的情况下,输出是:

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 256
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1418
virtual memory          (kbytes, -v) unlimited

如您所见,open filesfile locks 等于 256

open files                      (-n) 256

这是一个非常 small 的值

@carl 的存档至少包含超过 256 个文件;所以python使用文件处理程序打开每个文件,然后导致system file lock(为了在系统上打开文件,你需要一个文件锁,就像指向该文件的指针;要访问数据,做任何你想做的事)

解决方案是将open files 的值设置为unlimitedvery big 数字。

根据stack answer,这是您可以更改限制的方法

【讨论】:

  • 但我总是关闭文件,每次只打开一个文件。所以我不太明白为什么我会遇到这个问题。我的代码中一定有一些东西没有正确关闭文件,我宁愿找到这个错误,而不是仅仅将此限制设置为更大的数字。
猜你喜欢
  • 2020-03-07
  • 1970-01-01
  • 2016-04-21
  • 1970-01-01
  • 1970-01-01
  • 2018-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多