2015-08-22 43 views
1

我遇到了以下问题:Python多处理 - 两个进程之间的函数式通信

我有两个不同的类;我们称他们为interfaceworker。该接口应该接受来自外部的请求,并将它们复用到多个工作人员。

相反,我发现几乎每一个例子,我有几个特点:

  • 工人不应该被重建为每个请求。
  • 工人是不同的;请求workers[0]无法通过workers[1]回答。该复用在interface中完成。
  • 我有一些类似函数的调用很难通过事件或简单的队列进行建模。
  • 有几个不同的请求,这将使每个请求的一个队列变得困难。

例如,假设每个工作人员正在存储一个整数(假设这个工作人员收到的调用次数)。在非并行处理,我会使用这样的:

class interface(object): 
    workers = None #set somewhere else. 

    def get_worker_calls(self, worker_id): 
     return self.workers[worker_id].get_calls() 

class worker(object) 
    calls = 0 

    def get_calls(self): 
     self.calls += 1 
     return self.calls 

 

显然,这是行不通的。什么?

或者,也许更相关的是,我没有多处理经验。有没有我很想念的设计范例,可以轻松解决上述问题?

谢谢!

 

 

仅供参考,我也考虑过几种方法,而我无法找到一个很好的一个:

  • 使用一个请求和回答队列。我放弃了这个想法,因为它会阻止interface'为当前工作人员的回答时间(使其可扩展性极差),或者需要我发送额外的信息。
  • 使用一个请求队列。每条消息都包含一个管道以返回该请求的答案。修复issue with being unable to send pipes via pipes后,我遇到了管道关闭的问题,除非通过连接发送两端。
  • 使用一个请求队列。每条消息都包含一个队列以返回该请求的答案。由于无法通过队列发送队列,因此失败,但减少技巧不起作用。
  • 以上内容也适用于相应的管理器生成的对象。

回答

0

多处理意味着你有2+分离的进程运行。没有办法直接从一个进程访问内存(如同多线程一样)。

你最好的办法是使用某种外部队列机制,你可以从CeleryRQ开始。 RQ更简单,但芹菜具有内置监控功能。

但是你必须知道,只有当Celery/RQ能够“包装”所需的功能/类并将它们发送到其他进程时,多处理才能工作。因此,您必须使用__main__级别的函数(位于文件顶部,不属于任何类)。

你可以自己实现它,Redis很简单,ZeroMQ和RabbitMQ也不错。

Beaver library是如何处理Python中使用ZeroMQ队列的多处理的好例子。