【问题标题】:share python object between multiprocess in python3在python3中的多进程之间共享python对象
【发布时间】:2017-02-02 21:01:46
【问题描述】:

这里我创建一个生产者-客户程序,父进程(生产者)创建多个子进程(消费者),然后父进程读取文件并将数据传递给子进程。

但是,这里出现了一个性能问题,在进程之间传递消息花费了太多时间(我认为)。

例如,200MB原始数据,父进程读取和预处理将花费不到8秒,而不是通过多进程将数据传递给子进程。pipe 将花费另外 8 秒,而子进程完成剩余工作只需花费另外 3 ~ 4 秒。

所以,一个完整的工作流程花费不到 18 秒,进程之间的通信花费超过 40% 的时间成本,比我想象的要大得多,我尝试了多进程。队列和经理,他们更糟糕。

我使用 windows7 / Python3.4。 我google了好几天,POSH可能是一个很好的解决方案,但它不能用python3.4构建

我有 3 种方法:

1.有没有什么办法可以直接在Python3.4中的进程之间共享python对象?作为POSH

或

2.是否可以将对象的“指针”传递给子进程,子进程可以恢复指向python对象的“指针”?

或

3.multiprocess.Array 可能是一个有效的解决方案,但如果我想共享复杂的数据结构,例如列表,它是如何工作的?我应该基于它创建一个新类并提供接口作为列表吗?

编辑1: 我尝试了第三种方法,但效果更差。
我定义了这些值:

p_pos = multiprocessing.Value('i') #producer write position  
c_pos = multiprocessing.Value('i') #customer read position  
databuff = multiprocess.Array('c',buff_len) # shared buffer

还有两个功能:

send_data(msg)  
get_data()

在send_data函数(父进程)中,将msg复制到databuff,并通过管道将开始和结束位置(两个整数)发送给子进程。
与 get_data 函数(子进程)相比,它接收到两个位置并从 databuff 复制 msg。

最终,它的成本是使用管道@_@的两倍

编辑 2:
是的,我试过 Cython,结果看起来不错。
我只是将我的python脚本的后缀更改为.pyx并编译它,程序速度提高了15%。
毫无疑问,我遇到了“无法找到 vcvarsall.bat”和“系统找不到指定的文件”错误,我花了一整天的时间解决了第一个问题,并被第二个阻止了。
终于,我找到了Cyther,所有的烦恼都过去了^_^。

【问题讨论】:

  • 我想要的只是一个队列,父进程将消息放入,子进程从中取出消息,并且在多进程模块中没有过多的移动操作,例如管道或队列

标签: multithreading performance python-3.x communication


【解决方案1】:

五个月前我在你家。我环顾四周,但我的结论是 Python 的多处理正是您所描述的问题:

我通过学习C++解决了这类问题,但可能不是你想读的……

【讨论】:

  • 谢谢。所以这个瓶颈是python本身解决的。你说你“通过学习C++解决了这种问题”,意思是你用C++重写了所有程序?还是只是进程之间的通信?
  • 通常我只重写需要的东西,所以正如你所说的进程之间的通信,我使用 boost.python 或 Cython 取回我的函数。这很难,但只是第一次;)
  • @ Jean-Baptiste F. 非常感谢,我会试试 Cython。
  • 不客气,如果您认为是这样,请将问题标记为已回答!
【解决方案2】:

要将数据(尤其是大型 numpy 数组)传递给子进程,我认为 mpi4py 可以非常高效,因为我可以直接处理类似缓冲区的对象。

可以在here 找到使用 mpi4py 生成进程和通信的示例(也使用 trio,但这是另一回事)。

【讨论】:

  • 感谢您的回答,这是一个非常古老的问题,我提出这个问题的办公室已经关闭......但仍然感谢。我访问了mpi4py的官方页面,它看起来有点像“fork”,我会尝试并测量性能,希望它可以像共享内存一样工作。
猜你喜欢
  • 2012-07-22
  • 1970-01-01
  • 2023-03-24
  • 2019-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-16
  • 2021-10-21
相关资源
最近更新 更多