python mmap.error:打开的文件过多。 怎么了?

我正在用pupynere接口(linux)读一堆netcdf文件。 以下代码导致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命令(要么!)!它的作品! 我究竟做错了什么? 我正在closures文件,对不对? 这是某种程度上与python列表相关的。 我使用了一种不同的效率低下的方法(总是复制每个元素)。

PS: ulimit -n得到1024,程序在文件编号498失败。

也许有关,但解决scheme不适合我: NumPy和memmap:[Errno 24]打开的文件太多

我的猜测是pupynere中的mmap.mmap调用是将文件描述符保存为打开(或创建一个新的)。 如果你这样做:

 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可能会修复它? 只是一个WILD的猜测。


编辑: curData是否有Flush方法,偶尔? 你有没有试过在Close之前调用?


编辑2: with声明的Python 2.5's(从理解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()