繁体   English   中英

如何从多处理队列继承?

[英]How to inherit from a multiprocessing queue?

使用以下代码,似乎传递给worker的队列实例未初始化:

from multiprocessing import Process
from multiprocessing.queues import Queue

class MyQueue(Queue):

    def __init__(self, name):
        Queue.__init__(self)
        self.name = name

def worker(queue):
    print queue.name

if __name__ == "__main__":
    queue = MyQueue("My Queue")
    p = Process(target=worker, args=(queue,))
    p.start()
    p.join()

抛出:

... line 14, in worker
    print queue.name
AttributeError: 'MyQueue' object has no attribute 'name'

我无法重新初始化队列,因为我将丢失queue.name的原始值,甚至将队列的名称作为参数传递给worker(这应该可行,但它不是一个干净的解决方案)。

那么,如何从multiprocessing.queues.Queue继承而不会出现此错误?

在POSIX上,通过简单继承将Queue对象共享给子进程。*

在Windows上,这是不可能的,所以它必须挑选Queue ,通过管道将其发送给孩子,并取消它。

(这可能不是很明显,因为如果你实际上试图RuntimeError: MyQueue objects should only be shared between processes through inheritance一个Queue ,你会得到一个异常, RuntimeError: MyQueue objects should only be shared between processes through inheritance 。如果你查看源代码,你会看到这是真的谎言 - 如果你在multiprocess进程没有产生子进程的过程中尝试挑选一个Queue ,它只会引发这个异常。)

当然,通用的pickle和unpickling不会有任何好处,因为你最终会得到两个相同的队列,而不是两个进程中的相同队列。 因此, multiprocessing通过为unpickling中使用的对象添加register_after_fork机制来扩展一些内容。**如果查看Queue的源代码 ,您可以看到它是如何工作的。

但你真的不需要知道它是如何起作用的; 你可以像任何其他类的酸洗一样挂钩它。 例如,这应该工作:***

def __getstate__(self):
    return self.name, super(MyQueue, self).__getstate__()

def __setstate__(self, state):
    self.name, state = state
    super(MyQueue, self).__setstate__(state)

有关详细信息, pickle文档解释了影响课程腌制方式的不同方法。

(如果它不工作,我还没有做出愚蠢的错误...那么必须知道至少有一点它是如何工作挂钩...但最有可能只是弄清楚之前,是否做你的额外的工作或者在_after_fork()之后, _after_fork()需要交换最后两行...)


*我不确定它实际上保证在POSIX平台上使用简单的fork继承。 在2.7和3.3上恰好是这样。 但是有一个multiprocessing的分支,它使用Windows风格的pickle-所有平台上的所有内容保持一致性,另一个使用OS X上的混合允许在单线程模式下使用CoreFoundation ,或类似的东西,它显然是可行的那样。

**实际上,我认为 Queue只是为了方便而使用register_after_fork ,并且可以在没有它的情况下进行重写......但这取决于Pipe在Windows上的_after_fork或者POSIX上的LockBoundedSemaphore所做的魔术。

***这只是正确的,因为我碰巧知道,从阅读源代码, Queue是一个新式的类,不会覆盖__reduce____reduce_ex ,并且永远不会从__getstate__返回falsey值。 如果您不知道,那么您必须编写更多代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM