我读到RawArray
可以在进程之间共享而无需复制,并希望了解它在Python中是如何实现的。
我在 sharedctypes.py 中看到,RawArray
是由 heap.py 的BufferWrapper
构造的,然后用ctypes.memset
作废。
BufferWrapper
由一个Arena
对象组成,该对象本身是从mmap
构建的(或 Windows 中的 100 mmap,请参阅 heap.py 中的第 40 行)
我读到mmap
系统调用实际上是用来在 Linux/BSD 中分配内存的,Python 模块使用 MapViewOfFile for windows。
mmap
似乎很方便。它似乎可以直接与mp.pool
一起工作——
from struct import pack
from mmap import mmap
def pack_into_mmap(idx_nums_tup):
idx, ints_to_pack = idx_nums_tup
pack_into(str(len(ints_to_pack)) + 'i', shared_mmap, idx*4*total//2 , *ints_to_pack)
if __name__ == '__main__':
total = 5 * 10**7
shared_mmap = mmap(-1, total * 4)
ints_to_pack = range(total)
pool = Pool()
pool.map(pack_into_mmap, enumerate((ints_to_pack[:total//2], ints_to_pack[total//2:])))
我的问题是——
多通道模块如何知道不要在进程之间复制基于mmap
的RawArray
对象,就像它对"常规"python对象所做的那样?
[Python 3.Docs]:多处理 - 基于进程的并行性使用专有协议序列化/反序列化进程之间交换的数据:[Python 3.Docs]:pickle - Python 对象序列化(从这里开始术语:pickle/unpickle)。
根据[Python 3.Docs]:pickle - object。__getstate__():
类可以进一步影响其实例的酸刻化方式;如果类定义了方法 __getstate__(),则会调用该方法,并且返回的对象将作为实例的内容进行剖析,而不是实例字典的内容。如果不存在 __getstate__() 方法,则实例的__dict__将照常进行酸洗。
如(Win变体)Arena.__getstate__所示,(类链:共享类型。RawArray ->堆。BufferWrapper ->堆。堆 ->堆。Arena),只有元数据(名称和大小)被腌制为Arena实例,而不是缓冲区本身。
相反,在__setstate__中,缓冲区是基于(上述)元数据构造的。