【问题标题】:Using mmap with popen将 mmap 与 popen 一起使用
【发布时间】:2011-09-24 13:06:25
【问题描述】:

我需要读入并处理一堆约 40mb 的 gzip 压缩文本文件,我需要快速完成并以最小的 I/O 开销(因为其他人也使用这些卷)。因此,我为此任务找到的最快方法如下所示:

def gziplines(fname): 
    f = Popen(['zcat', fname], stdout=PIPE)
    for line in f.stdout:
        yield line

然后:

for line in gziplines(filename)
    dostuff(line)

但我想做的(如果这更快?)是这样的:

def gzipmmap(fname): 
    f = Popen(['zcat', fname], stdout=PIPE)
    m = mmap.mmap(f.stdout.fileno(), 0, access=mmap.ACCESS_READ)
    return m

不幸的是,当我尝试这个时,我得到了这个错误:

>>> m = mmap.mmap(f.stdout.fileno(), 0, access=mmap.ACCESS_READ)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
mmap.error: [Errno 19] No such device

尽管如此,当我尝试时:

>>> f.stdout.fileno()
4

所以,我想我对这里发生的事情有一个基本的误解。 :(

这两个问题是:

1) 这种 mmap 是否是一种将整个文件放入内存进行处理的更快方法?

2) 我怎样才能做到这一点?

非常感谢...这里的每个人都已经非常乐于助人了! ~尼克

【问题讨论】:

  • 无论如何,您的生成器解决方案比使用 mmap 更清晰。您是否尝试过使用 Python 的标准 gzip 库,而不是调用外部程序? docs.python.org/library/gzip.html

标签: python subprocess popen mmap zcat


【解决方案1】:

来自mmap(2) 手册页:

   ENODEV The  underlying  file system of the specified file does not sup-
          port memory mapping.

您不能映射流,只能映射真实文件或匿名交换空间。您需要自己从流中读取到内存中。

【讨论】:

  • 谢谢。一年多后回到这个话题……对 mmap 和其他一切有了更好的理解!
【解决方案2】:

管道不可映射。

case MAP_PRIVATE:
      ...
if (!file->f_op || !file->f_op->mmap)
        return -ENODEV;

并且管道的文件操作不包含mmap钩子。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-25
    • 1970-01-01
    • 2015-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多