1

在普通代码中,一切都很好,我可以正确读/写。

for i in range(10):
    sleep(1)

    m = mmap.mmap(-1, 1024, access=mmap.ACCESS_WRITE, tagname='share_mmap')
    m.seek(0)
    cnt = m.read_byte()

    if cnt == 0:
        print("Load data to memory")
        m.seek(0)
        m.write(b"FFFFFFFFFFFFFFFFFF")

    else:
        m.seek(0)
        info_str=m.read().translate(None, b'\x00').decode()
        print("The data is in memory: ", info_str)

结果:

> Load data to memory
> The data is in memory:  FFFFFFFFFFFFFFFFFF
> The data is in memory:  FFFFFFFFFFFFFFFFFF

但是如果我用 包装它contextlib,就像所有教程的代码一样,那么我就无法再阅读了。

for i in range(10):
    sleep(1)

    # !!!! LOOK AT HERE !!!! I only changed this line.
    with contextlib.closing(mmap.mmap(-1, 1024, access=mmap.ACCESS_WRITE,
                            tagname='share_mmap')) as m:
        m.seek(0)
        cnt = m.read_byte()

        if cnt == 0:
            print("Load data to memory")
            m.seek(0)
            m.write(b"FFFFFFFFFFFFFFFFFF")

        else:
            m.seek(0)
            info_str=m.read().translate(None, b'\x00').decode()
            print("The data is in memory: ", info_str)

结果:

> Load data to memory
> Load data to memory
> Load data to memory

为什么? 还有,为什么大家都喜欢这样——他们没有遇到过这个bug吗?

4

2 回答 2

1

您正在映射匿名内存而不是文件,因此唯一让您每次都获得相同映射的是标签名称。如果您已经有一个具有给定标签名称的映射,则mmap再次为您提供相同的映射,但如果没有,您将获得一个新的映射。您的第一个片段有效,因为旧映射仍然存在(因为您从未关闭它们),但在您的第二个片段中,旧映射在新映射创建之前就消失了,并且由于它是匿名内存,这意味着数据也消失了.

要解决这个问题,要么在循环外进行映射,要么映射文件支持的内存。

于 2021-07-04T21:16:37.047 回答
0

显然它不适用于匿名内存(fileno -1),因为它适用于如下所示的真实文件。不确定这是一个错误,还是只是一个未记录的限制。

import contextlib
import mmap
from time import sleep
import tempfile


with tempfile.TemporaryFile() as mmapfile:
    for i in range(5):
        sleep(1)

        # Works if you use a real file.
        with contextlib.closing(mmap.mmap(mmapfile.fileno(), 1024, access=mmap.ACCESS_WRITE,
                                tagname='share_mmap')) as m:
            m.seek(0)
            cnt = m.read_byte()

            if cnt == 0:
                print("Load data to memory")
                m.seek(0)
                m.write(b"FFFFFFFFFFFFFFFFFF")

            else:
                m.seek(0)
                info_str=m.read().translate(None, b'\x00').decode()
                print("The data is in memory: ", info_str)

输出:

Load data to memory
The data is in memory:  FFFFFFFFFFFFFFFFFF
The data is in memory:  FFFFFFFFFFFFFFFFFF
The data is in memory:  FFFFFFFFFFFFFFFFFF
The data is in memory:  FFFFFFFFFFFFFFFFFF
于 2021-07-04T21:12:09.607 回答