2

multiprocessing在 Windows 上的 Python 2.7 上使用该模块,并且我有多个进程将数据放入共享队列并从共享队列中取出数据。我正在创建子类multiprocessing.Process来执行此操作,并将由 amultiprocessing.Manager()作为参数生成的队列代理传递给__init__. 在关于 SO 的其他答案中,我看到人们将此队列代理map_async作为参数传递,但是当我尝试将它作为__init__方法的参数提供时,我得到了错误:

TypeError: Pickling an AuthenticationString object is disallowed for security reasons

所以我知道在 Windows 上,您传递给实例化子Process类的东西必须是可腌制的,并且这些共享对象上需要有一个 authkey(这可以防止腌制)。但是为什么你可以给那个队列代理map_async而不是一个Process子类呢?Process除了将我的子类重写为函数之外,还有什么好的方法吗?

4

1 回答 1

3

map_async不等同于Process使用给定参数初始化/运行 a ,apply_async是。 map_async在您的示例中获取一个可迭代的 a Manager.Queue,将其拆分为批次(有效地将其解包/重新打包为一系列元组),然后启动工作人员并移交批次,而不是原始的可迭代。 apply_async,或者直接启动该过程,实际上将您提供的确切对象作为他们的参数之一传递给工作人员。您还碰巧使用了s 中的代理Queue,并且sManager生成的所有代理都附加了一个成员,正如您的错误所述,出于安全原因,它是不可提取的,因此不能传播给工作人员。ManagerAuthenticationString

你使用 aManager来生产你的有什么原因Queue吗?除非您通过网络或其他方式使用它,否则您应该可以使用标准multiprocessing.Queue,它不会有可挑选性问题(因为它源于Manager代理)。

顺便说一句,至少从我对代码的阅读来看,看起来使用 a Manager.Queue,甚至是常规的 oldmultiprocessing.QueueQueue作为输入map_async是相当没有意义的,因为被映射的可迭代对象在创建任何工作人员之前就已在父进程中完全消耗,然后再也没看过。

于 2013-07-10T20:21:00.987 回答