1 回答

TA贡献1712条经验 获得超3个赞
问题在于您正在尝试np.memmap
在流程之间传递a ,而这是行不通的。
最简单的解决方案是改为传递文件名,并让子进程处理memmap
相同的文件。
当您通过通过参数将参数传递给子进程或池方法multiprocessing
,或者从一个参数返回值(包括通过间接返回ProcessPoolExecutor
)时,它通过调用pickle.dumps
该值,在各个进程之间传递泡菜来工作(细节有所不同,但是不会)不管是aPipe
还是aQueue
或其他),然后从另一侧解开结果。
Amemmap
基本上只是在ped内存中分配了一个mmap
对象。ndarray
mmap
而且Python不知道如何腌制mmap
对象。(如果尝试这样做,则将得到aPicklingError
或BrokenProcessPool
错误,具体取决于您的Python版本。)
np.memmap
可以腌制A ,因为它只是的子类,np.ndarray
但是腌制和去腌制实际上会复制数据并为您提供一个简单的内存数组。(如果您看的话data._mmap
,它是None
。)如果它给您一个错误而不是静默地复制所有数据(pickle-replacement库dill
完全是这样:),则可能会更好TypeError: can't pickle mmap.mmap objects
,但事实并非如此。
在进程之间传递底层文件描述符不是不可能的-每个平台上的细节都不同,但是所有主要平台都可以做到这一点。然后,您可以使用传递的fdmmap
在接收端构建一个,然后再构建一个memmap
。您甚至可以将其包装到的子类中np.memmap
。但是我怀疑这是否有点困难,有人会做到这一点,实际上dill
,如果不是numpy
它本身,那可能已经成为它的一部分。
另一种选择是显式使用的共享内存功能multiprocessing
,并在共享内存而不是中分配数组mmap
。
但是,最简单的解决方案是,就像我在顶部所说的那样,只是传递文件名而不是对象,并让每一侧memmap
使用相同的文件。不幸的是,这确实意味着您不能只使用关闭时删除功能NamedTemporaryFile
(尽管您使用它的方式已经不可移植,并且在Windows上无法像在Unix上那样工作),但是改变了与其他替代方案相比,这项工作的工作量可能仍然更少。
添加回答
举报