python mmap.error: слишком много открытых файлов.В чем дело? - PullRequest
4 голосов
/ 29 апреля 2011

Я читаю кучу netcdf файлов с использованием интерфейса pupynere (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 (любая из них подойдет!) это работает!Что я делаю неправильно?Я закрываю файл, верно?Это как-то связано со списком питонов.Я использовал другой, неэффективный подход до (всегда копируя каждый элемент), который сработал.

PS: ulimit -n дает 1024, ошибка программы при номере файла 498.

может быть связано с, но решение не работает для меня: NumPy и memmap: [Errno 24] Слишком много открытых файлов

Ответы [ 4 ]

6 голосов
/ 29 апреля 2011

Я предполагаю, что вызов mmap.mmap в pupynere удерживает дескриптор файла открытым (или создает новый). Что делать, если вы делаете это:

vals.append(curData.variables['O3.MIXING.RATIO'][:].copy())
alts.append(curData.variables['ALTITUDE'][:].copy())
3 голосов
/ 29 апреля 2011

@ corlettk: да, так как это linux, do 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
2 голосов
/ 29 апреля 2011

Хммм ... Может, просто может быть, with curData может это исправить?Просто WILD догадка.


РЕДАКТИРОВАТЬ: Имеет ли curData метод Flush, случайно?Вы пробовали вызывать это до Close?


РЕДАКТИРОВАТЬ 2: выражение with Python 2.5 (снято прямо с Понимание выражения Python "with" )

with open("x.txt") as f:
    data = f.read()
    do something with data

... в основном это ВСЕГДА закрывает ресурс (очень похоже на конструкцию C # using).

1 голос
/ 29 апреля 2011

Сколько стоит 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()
...