Почему у python есть ограничение на количество файлов?

Я написал простой код для проверки, сколько файлов может быть открыто в python script:

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'

Ответы

Ответ 1

Количество открытых файлов ограничено операционной системой. В linux вы можете ввести

ulimit -n

чтобы узнать, что такое предел. Если вы являетесь пользователем root, вы можете ввести

ulimit -n 2048

теперь ваша программа будет работать нормально (с правами администратора), так как вы сняли ограничение до 2048 открытых файлов

Ответ 2

Скорее всего, потому, что операционная система имеет ограничение на количество файлов, которые приложение может открыть.

Ответ 3

Я вижу такое же поведение в Windows при запуске вашего кода. Предел существует из времени выполнения C. Вы можете использовать win32file для изменения предельного значения:

import win32file

print win32file._getmaxstdio()

Вышеуказанное даст вам 512, что объясняет сбой в # 509 (+ stdin, stderr, stdout, как уже указывали другие)

Выполните следующее, и ваш код будет работать нормально:

win32file._setmaxstdio(2048)

Обратите внимание, что 2048 является жестким пределом, хотя (жесткий предел лежащего в основе C Stdio). В результате выполнение множителя _setmaxstdio со значением больше 2048 не подходит для меня.

Ответ 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)

Ответ 5

Так как это не проблема Python, сделайте следующее:

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

Ниже приведена плохая идея очень.

fps.append(h)

Ответ 6

Приложение необходимо, чтобы сборщик мусора не очищал и не закрывал файлы