我在Windows上使用Python 2.7上的multiprocessing
模块,我有多个进程将数据放入共享队列并从中获取数据。我正在继承multiprocessing.Process
来执行此操作,并将multiprocessing.Manager()
生成的队列代理作为参数传递给__init__
。在SO的其他答案中,我看到人们将此队列代理作为参数传递给map_async
,但当我尝试将其作为__init__
方法的参数时,我得到错误:
TypeError: Pickling an AuthenticationString object is disallowed for security reasons
所以我理解在Windows上你传递给实例化Process
子类的东西必须是可以发现的,并且需要在这些共享对象上有一个authkey(这会阻止酸洗)。但是为什么你可以将该队列代理提供给map_async
而不是Process
子类?除了将我的Process
子类重写为函数之外,还有什么好办法吗?
答案 0 :(得分:3)
map_async
不等同于使用给定参数初始化/运行Process
,apply_async
是。 map_async
采用可迭代的,在您的示例中为Manager.Queue
,将其拆分为批次(有效地将其拆分/重新打包为一系列元组),然后启动工作人员并将批次交给批次,而不是原始的可迭代。 apply_async
,或者直接启动进程,实际上将您提供的确切对象作为其参数之一传递给worker。您也恰好使用Queue
中的代理Manager
,并且Manager
生成的所有代理都附加了AuthenticationString
成员,因为您的错误状态,出于安全原因不可销售,因此不能传播给工人。
您是否有理由使用Manager
制作Queue
?除非您通过网络或其他方式使用它,否则使用标准multiprocessing.Queue
就可以了,它不具备可挑选性问题(因为它来自于Manager
代理)。
顺便说一句,至少在我阅读代码时,看起来好像使用Manager.Queue
,甚至是常规的multiprocessing.Queue
或Queue
作为map_async
的输入因为映射的可迭代在创建任何工作者之前在父进程中被完全消耗,所以从未再次查看过。