如何使python mmap分配原子化?

如何使python mmap分配原子化?,python,Python,如何使python mmap分配原子化?这里没有关于原子的内容: 我立即在另一个进程中执行以下代码 f = open('mmp', 'r') m = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) mm = m[:] l = struct.unpack("100000000I", mm) set(l) 然后我看到{8889999} 这意味着mmap不是原子的。无论如何,要使其原子化?我不认为这是mmap问题-我敢打赌,这是因为f.close(

如何使python mmap分配原子化?这里没有关于原子的内容:

我立即在另一个进程中执行以下代码

f = open('mmp', 'r')
m = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
mm = m[:]
l = struct.unpack("100000000I", mm)
set(l)
然后我看到{8889999}


这意味着mmap不是原子的。无论如何,要使其原子化?

我不认为这是
mmap
问题-我敢打赌,这是因为
f.close()
只保证Python已将数据发送到底层操作系统的缓冲区,但这并不意味着它已被实际写入。然后,当您再次打开它,并将句柄赋予
mmap
时,您仍在对缓冲区进行操作

您可以在关闭文件之前尝试同步缓冲区,以确保所有内容都已写入:

import os

f = open('mmp', 'wb')
f.write(b1)
f.flush()
os.fsync(f.fileno()) 
f.close()
或者更好,让Python在发生错误时干净地处理关闭:

with open('mmp', 'wb') as f:
    f.write(b1)
    f.flush()
    os.fsync(f.fileno())
尽管即使是
os.fsync()
也不是100%的保证,但从底层
fsync()
手册页:

调用fsync()不一定确保包含该文件的目录中的条目也已到达磁盘。为此,还需要在目录的文件描述符上使用显式fsync()


但我敢打赌,在非常罕见的边缘情况下,它不能满足您的需要。

一般来说,您不能。文件写入从一开始就不是原子的,无论是通过mmap还是write完成的。一些文件系统,比如Tahoe LAFS,确实有一个文件put操作,但即使在那里,这也是一个已知的完成问题,而不是原子操作(块单独存储)。文件内容更新的原子性通常通过以下三种方法完成:

  • 使用调用,您可以确保名称指向旧文件或新文件(Python可能更清楚)。这是例如中使用的方法

  • 使用。它们通常是协作的,这意味着所有访问文件的程序必须一致地使用相同的锁定方法。有时这是不可能的,例如跨某些网络文件系统。由于这种不一致性,还使用了其他锁方法,例如,也就是“相同的方法”要求

  • 由于底层架构(如磁盘扇区)的原因,使用较小的原子访问。这是通过例如在中完成的。值得注意的是,该阈值与mmap不同,因为内存页本身可以共享,从而允许更精细的原子访问粒度(可能是CPU字大小或单个字节)


  • 这个话题相当复杂。将这些同步方法中的任何一种与mmap相结合的关键是

    不确定是否有一个方法,除了通常写其他文件和重命名的顶部。我不认为你可以使用一个锁来代替原子锁?这是一个挑剔的问题,
    b2
    赋值不应该是:
    b2=struct.pack(“10000000i”,巨大的列表2)
    ?它的显示方式在任何情况下都不会进入文件。旁注:支持缓冲区接口以及fromfile/tofile,和比struct更有效地处理数据。我认为提问者同时运行这些代码片段。@user2357112-我理解他的问题的方式是,他有一个问题,即当他最初的文件写入与
    mmap
    写入混合时,数据被分散,这可以从外部过程中观察到。
    with open('mmp', 'wb') as f:
        f.write(b1)
        f.flush()
        os.fsync(f.fileno())