关于使用numpy和共享数组进行多处理有很多问题。但在我看来,他们都很乐意在应用程序启动时提供数据,这意味着它可以毫不费力地进行内存映射。
相反,我正在尝试构建一个生成数据然后进行处理的框架。
基本上我有一个看起来像这样的管道
Source --> Filter --> Destination
| | |
| | |
------------------------------> Controller / GUI
源会发出新数据,在我的例子中是来自例如视频流(存储为numpy.ndarray
个实例)。过滤器对数据进行计算,目标进行进一步计算。
Controller / GUI只是为了能够显示预览,当前进度等。
我目前的设计是制作源,过滤器和目标multiprocessing.Process
实例,然后我有multiprocessing.Queue
个实例来连接这些过程。
但是使用队列(或管道)来共享数据意味着在每一步都复制数据。如果可能的话,最好避免使用这些副本,因为我非常肯定(尽管尚未测量)这会降低性能。 有没有合理的方法来避免这种情况?
我想我真正想要的是某种共享内存池,我可以存储图像,然后只传递对进程的引用。 例如:
k
的共享内存池中。k
处有新图片”来过滤k
处的图像。k
处的过滤后的图片”发送到目的地。我不确定实施有多困难,如果有人已经拥有,或者确实是最好的答案。 我想听听你的意见。
答案 0 :(得分:0)
您可能已成功将numpy数据存储在一个或多个multiprocessing.Manager
s中。您仍然需要处理与管理器来回串行化通信的性能影响,但如果您小心,您至少可以避免必须在pickle / unpickle之间抽取整个数据结构。
编辑:
也许你正在以错误的方式看问题。不是尝试将数据从一个处理实体传递到下一个处理实体,而是为每个数据实体创建一个工作者,然后在该一个工作者中执行该实体的所有计算。您是否可以构建代码,以便Source可以生成一个负责实际生成和过滤图像的工作者,然后让工作人员在完成新数据准备好演示时通知Destination?您仍然需要将某些令牌从Source序列化到工作者,以及从工作者到目标的最终数据,但是您可以摆脱至少1或2次切换,并且可能能够找出一种更有效的方法来序列化剩下的东西,因为你只需要序列化与目的地相关的部分数据。