5

我正在使用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命令(任何一条都可以!)它会起作用!我究竟做错了什么?我正在关闭文件,对吧?这在某种程度上与 python 列表有关。我之前使用了一种不同的、低效的方法(总是复制每个元素)。

PS:ulimit -n产生 1024,程序在文件号 498 处失败。

可能与,但解决方案对我不起作用:NumPy and memmap: [Errno 24] Too many open files

4

4 回答 4

6

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

vals.append(curData.variables['O3.MIXING.RATIO'][:].copy())
alts.append(curData.variables['ALTITUDE'][:].copy())
于 2011-04-29T11:33:00.287 回答
3

@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
于 2011-04-29T09:53:42.653 回答
2

嗯...也许,只是也许,with curData可以解决它?只是一个疯狂的猜测。


编辑:curDataFlush方法吗?你以前试过打电话Close吗?


编辑 2: Python 2.5 的with语句(直接从理解 Python 的“with”语句中提取)

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

...基本上它总是关闭资源(很像 C# 的using构造)。

于 2011-04-29T09:59:38.297 回答
1

电话有多贵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()
于 2011-04-29T09:53:40.587 回答