了解Python 3.8中的shared_memory

时间:2019-07-03 20:39:55

标签: python pickle python-multiprocessing shared-memory mmap

我正在尝试了解shared_memory的某些操作。

查看source,看起来该模块在UNIX环境中使用shm_open(),在Windows上使用CreateFileMapping \ OpenFileMapping,并与mmap结合使用。

here我了解到,为了避免通过pickle进行彻底的序列化/反序列化,一个人需要为其共享数据类型显式实现__setstate__()__getstate__()

shared_memory.py中看不到任何这样的实现。

shared_memory如何规避咸菜处理?

此外,在Windows计算机上,仅此一项似乎在所有解释程序中都可以幸免:

from mmap import mmap

shared_size = 12
shared_label = "my_mem"

mmap(-1, shared_size , shared_label)

为什么这里需要CreateFileMapping \ OpenFileMapping

1 个答案:

答案 0 :(得分:3)

  

shared_memory如何规避咸菜处理?

我认为您在进程之间混淆了共享的ctypes 共享的对象

首先,您不必使用multiprocessing提供的共享机制来获取共享对象,只需包装诸如mmap / Windows的基本原语或使用以下方法即可您的操作系统/内核向您提供的任何API。

接下来,您提到的有关如何完成复制以及__getstate__如何定义酸洗行为的第二个链接取决于您-使用sharedctypes模块API。您不必强制执行酸洗以在两个进程之间共享内存。

实际上,sharedctypes由匿名共享内存支持,该共享内存使用:https://github.com/python/cpython/blob/master/Lib/multiprocessing/heap.py#L31

两个实现都依赖于类似mmap的原语。

无论如何,如果您尝试使用sharedctype复制某些内容,则会出现:

此函数正在使用ForkingPickler,它将使用pickle,然后…最终,您将在某个地方调用__getstate__

但这与shared_memory无关,因为shared_memory实际上不是类似ctype的对象。

您还可以使用资源共享器/跟踪器API:https://github.com/python/cpython/blob/master/Lib/multiprocessing/resource_sharer.py通过pickle序列化/反序列化来使用其他方法在进程之间共享对象。

但是您不会通过共享内存共享共享内存,对吧?

使用时:https://github.com/python/cpython/blob/master/Lib/multiprocessing/shared_memory.py

您创建一个具有唯一名称的内存块,并且所有进程在共享该内存之前都必须具有唯一名称​​ ,否则您将无法附加它。

基本上,这个比喻是:

  

您有一群朋友,并且每个人都有一个独特的秘密基地,只有您拥有该位置,您才能出差,彼此远离,但是你们都可以在这个独特的位置见面。

为使此工作正常进行,在彼此分开之前,您必须都知道位置。如果您事先没有它,那么您不确定是否可以找到与他们会面的地方。

shared_memory相同,只需要打开它的名称即可。您不会在进程之间共享/转移shared_memory。您通过多个过程中的唯一名称读入shared_memory

结果,为什么要腌制它?您可以。你绝对可以腌制它。但这可能不是内置的,因为直接通过另一个共享内存通道或类似的方式将唯一名称发送给所有进程很简单。

这里不需要规避。 ShareableList只是SharedMemory类的应用示例。如您在这里看到的:https://github.com/python/cpython/blob/master/Lib/multiprocessing/shared_memory.py#L314

它需要类似于唯一名称的名称,您还可以使用匿名共享内存,并在以后通过另一个渠道传输其名称(编写一个临时文件,将其发送回某个API,无论如何)。

  

为什么这里需要CreateFileMapping \ OpenFileMapping?

由于它取决于您的Python解释器,因此您可能正在使用CPython,它正在执行以下操作:

https://github.com/python/cpython/blob/master/Modules/mmapmodule.c#L1440

它已经在间接使用CreateFileMapping,因此进行CreateFileMapping然后附加它只是在CPython中复制已经完成的工作。

但是,其他口译员呢?所有解释器是否都执行必要的操作,以使mmap在非POSIX平台上工作?也许开发人员的理由就是这样。

无论如何,mmap开箱即用也就不足为奇了。