Подтвердить что ты не робот

IOError: [Errno 24] Слишком много открытых файлов:

У меня есть огромный файл, который я пишу примерно в 450 файлах. Я получаю ошибку как too many files open. Я искал в Интернете и нашел какое-то решение, но это не помогает.

import resource
resource.setrlimit(resource.RLIMIT_NOFILE, (1000,-1))
>>> len(pureResponseNames) #Filenames 
434
>>> resource.getrlimit(resource.RLIMIT_NOFILE)
(1000, 9223372036854775807)
>>> output_files = [open(os.path.join(outpathDirTest, fname) + ".txt", "w") for fname in pureResponseNames]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 24] Too many open files: 'icd9_737.txt'
>>> 

Я также изменил ulimit из командной строки, как показано ниже:

$ ulimit -n 1200
$ 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) 1200
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 709
virtual memory          (kbytes, -v) unlimited
$ 

Я все еще получаю ту же ошибку. PS: Я также перезапустил свою систему и запустил программу, но без успеха.

4b9b3361

Ответ 1

"Слишком много открытых файлов" ошибки всегда сложны - вам не только нужно крутить с помощью ulimit, но вы также должны проверять ограничения в системе и особенности OSX. Это сообщение SO дает дополнительную информацию об открытых файлах в OSX. (Предупреждение о спойлере: по умолчанию 256).

Однако часто бывает легко ограничить количество файлов, которые должны быть открыты одновременно. Если мы посмотрим на пример Стефана Боллмана, мы можем легко изменить это на:

pureResponseNames = ['f'+str(i) for i in range(434)]
outpathDirTest="testCase/"
output_files = [os.path.join(outpathDirTest, fname) + ".txt" for fname in pureResponseNames]

for filename in range(output_files):
    with open(filename, 'w') as f:
        f.write('This is a test of file nr.'+str(i))

Ответ 2

Вы должны попробовать $ulimit -n 50000 вместо 1200

Ответ 3

Если по каким-либо причинам вы не можете закрыть файл (например, используете сторонний модуль), вы можете установить максимальный лимит hard вместо предопределенного жестко заданного лимита (он выдает ValueError, если вы пытаетесь установить hard+1):

import resource
soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE)
resource.setrlimit(resource.RLIMIT_NOFILE, (hard, hard))

И я хочу прояснить, что даже если вы вручную удалите файлы, созданные во время работы процесса python, он все равно выдаст такую ошибку позже.

Ответ 4

Минимальный рабочий пример будет приятным. Я получил те же результаты, что и ron.rothman, используя следующий script с Python 3.3.2, GCC 4.2.1 на mac 10.6.8. Вы получаете ошибки, используя его?

    import os, sys
    import resource
    resource.setrlimit(resource.RLIMIT_NOFILE, (1000,-1))
    pureResponseNames = ['f'+str(i) for i in range(434)]
    try:
        os.mkdir("testCase")
    except:
        print('Maybe the folder is already there.')
    outpathDirTest="testCase/"
    output_files = [open(os.path.join(outpathDirTest, fname) + ".txt", "w") for fname in pureResponseNames]
    for i in range(len(output_files)):
        output_files[i].write('This is a test of file nr.'+str(i))
        output_files[i].close()

Ответ 5

Я настоятельно не рекомендую вам увеличивать ulimit.

  1. Например, ваша база данных может сильно вырасти и привести к генерировать гораздо больше файлов, чем раньше, так много, что это стать больше, чем предел, который вы установили и сочтете достаточным.
  2. Это трудоемкая/подверженная ошибкам задача обслуживания, потому что вы бы необходимо убедиться, что каждая среда/сервер имеет этот предел правильно настроен и никогда не менялся.

Вы должны убедиться, что open используется в сочетании с close или что используется оператор with (который более питонический).

Сторонние библиотеки могут вызывать проблемы (например, pyPDF2 PdfFileMerger.append сохраняет файлы открытыми до тех пор, пока для них не будет вызван метод write). То, как я это отследил, довольно некрасиво, но попробовав пару вещей на сервере во время мониторинга количества открытых файлов, добился цели (мой локальный компьютер для разработки работает под Mac OS X, а сервер - CentO):

watch 'lsof | grep "something-created-filenames-have-in-common" | wc -l'