2010-12-08 78 views
21

我写了一种测试套件,它的文件密集程度很高。经过一段时间(2小时)后,我得到一张IOError: [Errno 24] Too many open files: '/tmp/tmpxsqYPm'。我再次检查所有文件句柄,不管我是否再次关闭它们。但是错误依然存在。python中打开的文件太多

我试图找出使用resource.RLIMIT_NOFILE允许的文件描述符的数量和当前打开的文件desciptors数量:

def get_open_fds(): 

    fds = [] 
    for fd in range(3,resource.RLIMIT_NOFILE): 
      try: 
        flags = fcntl.fcntl(fd, fcntl.F_GETFD) 
      except IOError: 
        continue 

      fds.append(fd) 

    return fds 

所以,如果我运行下面的测试:

print get_open_fds() 
for i in range(0,100): 
    f = open("/tmp/test_%i" % i, "w") 
    f.write("test") 
    print get_open_fds() 

我得到这个输出:

[] 
/tmp/test_0 
[3] 
/tmp/test_1 
[4] 
/tmp/test_2 
[3] 
/tmp/test_3 
[4] 
/tmp/test_4 
[3] 
/tmp/test_5 
[4] ... 

这很奇怪,我期待a增加打开的文件描述符的数量。我的脚本是否正确?

我正在使用python的记录器和子进程。这可能是我的FD泄漏的原因吗?

感谢, 丹尼尔

+0

请执行cat/proc/SYS/FS /文件-max和执行cat/proc/SYS/FS /文件-NR – 2010-12-08 10:39:23

+2

你应该使用`resource.getrlimit(resource.RLIMIT_NOFILE) `。 `resource.RLIMIT_NOFILE`只是一个访问信息的常量。 – chuck 2011-07-10 23:01:37

回答

11

你的测试脚本将覆盖f每次迭代中,这意味着该文件将每次获得封闭。记录到文件和subprocess与管道使用描述符,这可能会导致用尽。

8

resource.RLIMIT_NOFILE确实是7,但是这是一个索引resource.getrlimit(),而不是限制本身... resource.getrlimit(resource.RLIMIT_NOFILE)是你希望你的顶部范围()是

什么
11

改正的代码是:

import resource 
import fcntl 
import os 

def get_open_fds(): 
    fds = [] 
    soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE) 
    for fd in range(0, soft): 
     try: 
      flags = fcntl.fcntl(fd, fcntl.F_GETFD) 
     except IOError: 
      continue 
     fds.append(fd) 
    return fds 

def get_file_names_from_file_number(fds): 
    names = [] 
    for fd in fds: 
     names.append(os.readlink('/proc/self/fd/%d' % fd)) 
    return names 

fds = get_open_fds() 
print get_file_names_from_file_number(fds)