2010-12-08 11 views
21

schrieb ich ein bisschen eine Testsuite, die stark intensive Datei protokolliert. Nach einiger Zeit (2h) bekomme ich eine IOError: [Errno 24] Too many open files: '/tmp/tmpxsqYPm'. Ich habe alle Dateigriffe überprüft, ob ich sie wieder schließe. Aber der Fehler existiert immer noch.Zu viele offene Dateien in Python

Ich habe versucht, die Anzahl der erlaubten Datei-Deskriptoren, um herauszufinden, resource.RLIMIT_NOFILE und die Anzahl der aktuell geöffnete Datei desciptors mit:

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 

Also, wenn ich den folgenden Test durchgeführt:

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

ich dieser Ausgabe:

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

das seltsame ist, erwartete ich ein n zunehmende Anzahl von geöffneten Dateideskriptoren. Ist mein Skript korrekt?

Ich verwende Python des Loggers und subprocess. Könnte das der Grund für mein fd-Leck sein?

Danke, Daniel

+0

bitte cat/proc/sys/fs/file-max und cat/proc/sys/fs/file-nr –

+2

Sie verwenden sollten 'resource.getrlimit (resource.RLIMIT_NOFILE) '. 'resource.RLIMIT_NOFILE' ist nur eine Konstante, um auf die Informationen zuzugreifen. – chuck

+0

Würde subprocess.Popen ähnliche Probleme verursachen? – Joe

Antwort

11

Ihr Testskript f jede Iteration überschreibt, was bedeutet, dass die Datei jedes Mal geschlossen wird erhalten. Sowohl die Protokollierung von Dateien und subprocess mit Rohren aufbrauchen Deskriptoren, die bis zur Erschöpfung führen kann.

+0

meine Schuld, danke für den Hinweis! Es scheint, dass get_open_fds() seine Aufgabe erfüllt. Aber resource.RLIMIT_NOFILE = 7 und mein der Fehler tritt auf, nachdem ich 1024 Dateien geöffnet habe. Wie auch immer, ich weiß, wie ich meine Skripte debuggen kann - danke, bis jetzt !!! – dmorlock

+1

@Informant können Sie das Update auch posten? Ich habe das gleiche Problem, weiß aber nicht, wie ich es beheben kann. Danke. – AliBZ

8

resource.RLIMIT_NOFILE ist in der Tat 7, aber das ist ein Index in resource.getrlimit(), nicht die Grenze selbst ... resource.getrlimit (resource.RLIMIT_NOFILE) ist das, was Sie Ihren Top-Bereich() sein wollen

11

Der korrigierte Code ist:

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) 
Verwandte Themen