Trop de fichiers ouverts en python

j'ai écrit une sorte de suite test qui est fortement axée sur les fichiers. Après un certain temps (2h) j'obtiens un IOError: [Errno 24] Too many open files: '/tmp/tmpxsqYPm'. J'ai vérifié tous les descripteurs de fichiers si je ferme de nouveau. Mais l'erreur est toujours présente.

j'ai essayé de calculer le nombre de descripteurs de fichiers autorisés en utilisant resource.RLIMIT_NOFILE et le numéro de fichier actuellement ouvert 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

Donc, si je lance le test suivant:

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

j'obtiens ce résultat:

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

C'est étrange, je prévu un nombre croissant de descripteurs de fichiers ouverts. Est-ce que mon script est correct?

j'utilise le logger et le sous-processus de python. Peut-être la raison de ma fd fuite?

Merci, Daniel

21
demandé sur Paul D. Waite 2010-12-08 13:34:41

3 réponses

votre script de test écriraf chaque itération, ce qui signifie que le fichier sera fermé à chaque fois. Les deux journalisation de fichiers et subprocess avec des tuyaux d'utiliser jusqu'descripteurs, ce qui peut conduire à l'épuisement.

11
répondu Ignacio Vazquez-Abrams 2010-12-08 10:36:55

Le code corrigé:

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)
11
répondu dangonfast 2012-11-29 11:08:22

ressource.RLIMIT_NOFILE est en effet 7, mais c'est un index dans la ressource.getrlimit(), pas à la limite de lui-même... ressources.getrlimit (ressource.RLIMIT_NOFILE) est ce que vous voulez de votre haut de gamme ()

8
répondu Peter Buckner 2010-12-20 20:47:14