Python mmap.error: слишком много открытых файлов. Что случилось?
Вопрос
Я читаю кучу NetCDF файлы с использованием кучу Интерфейс (Linux). Следующий код приводит к ошибке MMAP:
import numpy as np
import os, glob
from pupynere import NetCDFFile as nc
alts = []
vals = []
path='coll_mip'
filter='*.nc'
for infile in glob.glob(os.path.join(path, filter)):
curData = nc(infile,'r')
vals.append(curData.variables['O3.MIXING.RATIO'][:])
alts.append(curData.variables['ALTITUDE'][:])
curData.close()
Ошибка:
$ python2.7 /mnt/grid/src/profile/contra.py
Traceback (most recent call last):
File "/mnt/grid/src/profile/contra.py", line 15, in <module>
File "/usr/lib/python2.7/site-packages/pupynere-1.0.13-py2.7.egg/pupynere.py", line 159, in __init__
File "/usr/lib/python2.7/site-packages/pupynere-1.0.13-py2.7.egg/pupynere.py", line 386, in _read
File "/usr/lib/python2.7/site-packages/pupynere-1.0.13-py2.7.egg/pupynere.py", line 446, in _read_var_array
mmap.error: [Errno 24] Too many open files
Интересно, Если я прокомментирую один из append
Команды (любой подойдет!) оно работает! Что я делаю не так? Я закрываю файл, верно? Это каким -то образом связано со списком Python. Я использовал другой, неэффективный подход до (Всегда копируя каждый элемент), который сработал.
PS: ulimit -n
Доходность 1024, программа не выполняется по номеру файла 498.
Может быть, связано, но решение не работает для меня: Numpy и Memmap: [Errno 24] Слишком много открытых файлов
Решение
Я предполагаю, что вызов mmap.mmap в Pupynere удерживает открытый дескриптор файла (или создает новый). Что если вы сделаете это:
vals.append(curData.variables['O3.MIXING.RATIO'][:].copy())
alts.append(curData.variables['ALTITUDE'][:].copy())
Другие советы
@corlettk: Да, так как это Linux, strace -e trace=file
Сделаю
strace -e trace=file,desc,munmap python2.7 /mnt/grid/src/profile/contra.py
Это покажет, какой именно файл открыт, когда - и даже дефицит файла.
Вы также можете использовать
ulimit -a
Чтобы увидеть, какие ограничения в настоящее время действуют
Редактировать
gdb --args python2.7 /mnt/grid/src/profile/contra.py
(gdb) break dup
(gdb) run
Если это приводит к слишком большому количеству точек останова перед теми, которые связаны с карманными файлами, вы можете запустить его без точек отдыха на некоторое время, сломайте его вручную (Ctrl+C) и установите точку останова во время «нормальной» операции; то есть, если у вас достаточно времени для этого :)
Как только он сломается, осмотрите стек вызовов с
(gdb) bt
Хммм ... может быть, просто может быть, with curData
Можно это исправить? Просто а ДИКИЙ предполагать.
РЕДАКТИРОВАТЬ: Делает curData
иметь Flush
Метод, Perchance? Вы пытались позвонить это раньше Close
?
РЕДАКТИРОВАТЬ 2:Python 2.5 with
заявление (поднято прямо из Понимание заявления Python «с»)
with open("x.txt") as f:
data = f.read()
do something with data
... в основном он всегда закрывает ресурс (очень похоже на C#' using
конструкция).
Насколько дорого nc()
вызов? Если это «достаточно дешево», чтобы запускать дважды на каждом файле, это работает?
for infile in glob.glob(os.path.join(path, filter)):
curData = nc(infile,'r')
vals.append(curData.variables['O3.MIXING.RATIO'][:])
curData.close()
curData = nc(infile,'r')
alts.append(curData.variables['ALTITUDE'][:])
curData.close()