Python mmap.error: demasiados archivos abiertos. ¿Qué ocurre?
Pregunta
Estoy leyendo un montón de netcdf archivos usando el pupynere interfaz (Linux). El siguiente código da como resultado un error 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()
Error:
$ 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
Curiosamente, Si comento uno de los append
Comandos (¡ya sea lo hará!) ¡funciona! ¿Qué estoy haciendo mal? Estoy cerrando el archivo, ¿verdad? Esto está de alguna manera relacionado con la lista de Python. Usé un enfoque diferente e ineficiente antes de (siempre copiando cada elemento) que funcionó.
PD: ulimit -n
rendimiento 1024, el programa falla en el número de archivo 498.
Tal vez relacionado con, pero la solución no funciona para mí: Numpy y MEMMAP: [ERRNO 24] Demasiados archivos abiertos
Solución
Supongo que la llamada MMAP.MMAP en Pupynere está manteniendo abierto el descriptor del archivo (o creando uno nuevo). ¿Qué pasa si haces esto?
vals.append(curData.variables['O3.MIXING.RATIO'][:].copy())
alts.append(curData.variables['ALTITUDE'][:].copy())
Otros consejos
@Corlettk: Sí, ya que es Linux, lo haz strace -e trace=file
servirá
strace -e trace=file,desc,munmap python2.7 /mnt/grid/src/profile/contra.py
Esto mostrará exactamente qué archivo se abre cuando, e incluso los disminucores del archivo.
También puedes usar
ulimit -a
Para ver qué limitaciones están actualmente vigentes
Editar
gdb --args python2.7 /mnt/grid/src/profile/contra.py
(gdb) break dup
(gdb) run
Si eso resulta en demasiados puntos de interrupción antes de los relacionados con los archivos asignados, es posible que desee ejecutarlo sin puntos de interrupción durante un tiempo, rómpelo manualmente (CTRL+C) y establece el punto de interrupción durante la operación 'normal'; es decir, si tienes suficiente tiempo para eso :)
Una vez que se rompe, inspeccione la pila de llamadas con
(gdb) bt
Hmmm ... tal vez, solo tal vez, with curData
¿Podría arreglarlo? Solo un SALVAJE suponer.
EDITAR: Lo hace curData
tener un Flush
método, perchance? ¿Has intentado llamar eso antes? Close
?
Editar 2:Python 2.5 with
declaración (levantada directamente de Comprender la declaración de Python "With")
with open("x.txt") as f:
data = f.read()
do something with data
... Básicamente, siempre cierra el recurso (al igual que C# using
construir).
¿Qué tan caro es el nc()
¿llamar? Si es 'lo suficientemente barato' para ejecutar dos veces en cada archivo, ¿funciona esto?
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()