【问题标题】:Why python has limit for count of file handles?为什么python对文件句柄的数量有限制?
【发布时间】:2011-07-21 10:38:39
【问题描述】:

我写了简单的代码进行测试,在python脚本中可以打开多少文件:

for i in xrange(2000):
    fp = open('files/file_%d' % i, 'w')
    fp.write(str(i))
    fp.close()

fps = []
for x in xrange(2000):
    h = open('files/file_%d' % x, 'r')
    print h.read()
    fps.append(h)

我得到一个例外

IOError: [Errno 24] Too many open files: 'files/file_509'

【问题讨论】:

  • 在 fedora 14 和 python 2.7 上我在 1021 上遇到了这个错误
  • @wiso, +stdin, stdout, stderr 得到 1024 - 我以前在哪里见过这个数字?
  • 您应该使用try..finallywith 来安全地关闭文件。对于您的问题:也许您想告诉我们您将要做什么,因为想要您的代码对我来说毫无意义。
  • @gnibber: ulimit -n 给了我 1024。我认为您还需要将 /usr/lib64/python2.7/atexit.py/home/xyz/.pystartup 算作打开的文件。
  • 如果你在同一个操作系统上用另一种语言尝试这个,你会很快发现这不是 Python 的限制。

标签: python


【解决方案1】:

打开文件的数量受操作系统限制。在 linux 上你可以输入

ulimit -n

看看限制是多少。如果你是root,你可以输入

ulimit -n 2048

现在您的程序可以正常运行(以 root 身份),因为您已将打开文件的限制提高到 2048 个

【讨论】:

  • +1,如果你想使用python代码检查限制,我会添加import resource; print resource.getrlimit(resource.RLIMIT_NOFILE)
  • 显然,你不需要root就可以改变它(我刚试过!)
【解决方案2】:

在运行您的代码时,我在 Windows 上看到了相同的行为。限制存在于 C 运行时。您可以使用 win32file 更改限制值:

import win32file

print win32file._getmaxstdio()

上面应该给你 512,它解释了 #509 的失败(+stdin,stderr,stdout,正如其他人已经说过的那样)

执行以下操作,您的代码应该可以正常运行:

win32file._setmaxstdio(2048)

请注意,2048 是硬限制(底层 C Stdio 的硬限制)。结果,执行值大于 2048 的 _setmaxstdio 对我来说失败了。

【讨论】:

  • 要完成这项工作,我首先必须进行此安装:pip install pywin32
【解决方案3】:

很可能是因为操作系统对应用程序可以打开的文件数量有限制。

【讨论】:

    【解决方案4】:

    要检查更改 Linux 上打开文件句柄的限制,您可以使用 Python 模块resource

    import resource
    
    # the soft limit imposed by the current configuration
    # the hard limit imposed by the operating system.
    soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE)
    print 'Soft limit is ', soft 
    
    # For the following line to run, you need to execute the Python script as root.
    resource.setrlimit(resource.RLIMIT_NOFILE, (3000, hard))
    

    在 Windows 上,我按照 Punit S 的建议进行操作:

    import platform
    
    if platform.system() == 'Windows':
        import win32file
        win32file._setmaxstdio(2048)
    

    【讨论】:

    • 我注意到我不必是 root 才能在 Ubuntu 中运行 setrlimit
    【解决方案5】:

    在 Windows 上,可以使用内置的 ctypes 库获取或设置限制:

    import ctypes
    print("Before: {}".format(ctypes.windll.msvcrt._getmaxstdio()))
    ctypes.windll.msvcrt._setmaxstdio(2048)
    print("After: {}".format(ctypes.windll.msvcrt._getmaxstdio()))
    

    【讨论】:

      【解决方案6】:

      由于这不是 Python 问题,请执行以下操作:

      for x in xrange(2000):
          with open('files/file_%d' % x, 'r') as h:
              print h.read()
      

      以下是一个非常糟糕的主意。

      fps.append(h)
      

      【讨论】:

      • 这是否是一个坏主意取决于你在做什么。甚至 Guido 自己也使用这种策略,在特定的排序算法中保留打开的文件:neopythonic.blogspot.com/2008/10/…
      • @S.Lott:您能解释一下为什么您认为 fps.append(h) 是个坏主意(以及您会建议哪种替代方案)?
      【解决方案7】:

      需要追加,因此垃圾收集器不会清理和关闭文件

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-09
        • 2010-11-13
        • 2013-05-19
        • 2011-10-21
        • 1970-01-01
        • 2010-10-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多