在天真地使用Python多处理过程中会遇到什么问题?
我们正在考虑重新构建一个大型应用程序,使用复杂的GUI,并以与后端分离的方式隔离,以使用新的(Python 2.6)多处理模块。 GUI /后端接口使用两个方向交换消息对象的队列。
我刚刚总结的一件事(暂时性的,但可以自由地确认它)是在多处理接口中不会保留“对象标识”。 目前,当我们的GUI向后端发布消息时,它期望获得相同的消息并将结果附加为属性。 它使用对象标识( if received_msg is message_i_sent:
以在某些情况下标识返回的消息......并且这似乎不适用于多处理。
这个问题是要问你在实际使用中看到了什么样的“陷阱”,或者想象一下,在天真地使用多处理模块时会遇到什么,尤其是在重构现有的单进程应用程序时。 请说明您的答案是否基于实际经验。 奖励积分为问题提供可用的解决方法。
编辑:尽管我对这个问题的意图是收集一般问题的描述,但我认为我犯了两个错误:我从一开始就将它制作为社区wiki(这可能会让很多人忽略它,因为它们不会获得声誉点) ,并且我列出了一个过于具体的例子,虽然我很欣赏答案,但可能会让很多人错过对一般回应的要求。 我可能会重新提出一个新问题并重新提出这个问题。 就目前而言,我只接受一个答案,仅仅是关于这个问题,只要它与我包含的具体例子相关。 感谢那些回答过的人!
我没有使用多处理技术,但提出的问题与我在其他两个领域的经验相似:分布式系统和对象数据库。 Python对象身份可以是祝福和诅咒!
至于一般性问题,如果您正在重构的应用程序可以确认任务正在异步处理,则会有所帮助。 如果不是这样,你通常最终会管理锁,并且使用单独进程可能获得的许多性能将会因等待这些锁而丢失。 我也会建议你花时间在各个流程上构建一些脚手架来进行调试。 真正的异步过程往往比心智可以持有和验证更多 - 或者至少是我的想法!
对于概述的特定情况,当物品排队并返回时,我将在流程边界管理对象标识。 发送要处理的任务时,使用id()对任务进行注释,并使用id()作为密钥将任务实例存储在字典中。 任务更新/完成时,从字典中检索id()返回的确切任务,并将新更新的状态应用于该任务。 现在确切的任务,因此它的身份,将保持。
那么,当然,在非单例对象上测试身份(例如“a是None”或“a False”)通常不是一个好习惯 - 它可能很快,但是一个真正快速的解决方法是交换“是”为“==”测试并使用增量计数器来定义身份:
# this is not threadsafe.
class Message(object):
def _next_id():
i = 0
while True:
i += 1
yield i
_idgen = _next_id()
del _next_id
def __init__(self):
self.id = self._idgen.next()
def __eq__(self, other):
return (self.__class__ == other.__class__) and (self.id == other.id)
这可能是一个想法。
此外,请注意,如果您拥有大量“工作进程”,内存消耗可能远远大于基于线程的方法。
你可以尝试我的项目GarlicSim中的persistent
包。 这是LGPL'ed。
http://github.com/cool-RR/GarlicSim/tree/development/garlicsim/garlicsim/misc/persistent/
(它的主要模块是persistent.py
)
我经常这样使用它:
# ...
self.identity = Persistent()
然后我有一个跨进程保留的身份。
链接地址: http://www.djcxy.com/p/43745.html上一篇: What problems will one see in using Python multiprocessing naively?