【问题标题】:Python 3.5 multiprocessing pool and queue don't workPython 3.5 多处理池和队列不起作用
【发布时间】:2017-04-01 10:15:13
【问题描述】:

我遇到了多处理问题。代码包含在下面。代码可以按预期执行,但是当取消注释self.queue = multiprocessing.Queue()时,这个程序会立即退出,似乎子进程无法启动成功。

我不知道发生了什么。有人可以帮我吗?非常感谢!

import multiprocessing
import time

class Test:
    def __init__(self):
        self.pool = multiprocessing.Pool(1)
        #self.queue = multiprocessing.Queue()

    def subprocess(self):
        for i in range(10):
            print("Running")
            time.sleep(1)
        print("Subprocess Completed")

    def start(self):
        self.pool.apply_async(func=self.subprocess)
        print("Subprocess has been started")
        self.pool.close()
        self.pool.join()

    def __getstate__(self):
        self_dict = self.__dict__.copy()
        del self_dict['pool']
        return self_dict

    def __setstate__(self, state):
        self.__dict__.update(state)

if __name__ == '__main__':
    test = Test()
    test.start()

【问题讨论】:

  • 任何traceback,如果有,请将其添加到您的问题中。
  • @stovfl 抱歉,我在 Pycharm 控制台中看不到任何回溯信息。如果取消注释该行,该程序将立即完成而无需等待其子进程。

标签: python python-3.x multiprocessing


【解决方案1】:

我可以重现您的问题,也没有提出Traceback
这应该会引发以下错误,不知道为什么:

RuntimeError: 队列对象只能通过继承在进程之间共享

将您的代码行替换为:

    m = multiprocessing.Manager()
    self.queue = m.Queue()  

为什么会出现这种情况?
multiprocessing.Queue 是用于一个 Process,你使用的是multiprocessing.Pool,它使用了多个Process,你必须使用 multiprocessing.Manager().Queue()

用 Python 测试:3.4.2

【讨论】:

  • 嗨,谢谢,这段代码 sn-p 在 Python 3.5 上适用于我。顺便说一下,如何显示 RuntimeError,即使使用控制台运行,我也看不到任何错误。非常感谢!
  • @mirage:也没给我看。我在另一个项目中遇到了这个运行时错误,使用mp.Manager() 是我找到的解决方案。
  • 我明白了。谢谢你的解释。
【解决方案2】:
  • 您使用 apply_async,它会立即返回。所以你应该在某个地方等待结果

  • 在后台,python 会将要执行的函数腌制到子进程。但是 self.process 作为一种方法在这里不能腌制(因为 self.pool 属性,请参阅下面 ShadowRanger 的评论)。


import multiprocessing
import time

def subprocess():   # is a plain old (pickle-able) function
    for i in range(10):
        print("Running")
        time.sleep(1)
    print("Subprocess Completed")
    return True

class Test:
    def __init__(self):
        self.pool = multiprocessing.Pool(1)

    def start(self):
        result = self.pool.apply_async(subprocess)
        print("Subprocess has been started")
        result.get()    # wait for the end of subprocess
        self.pool.close()
        self.pool.join()

if __name__ == '__main__':
    test = Test()
    test.start()

【讨论】:

  • 为了记录,一般酸洗方法没有错。但是默认的酸洗将不得不酸洗实例本身,以及它的所有属性(它们本身必须是可酸洗的)。由于Pool 是一个属性,而Pools 不可腌制,因此您不能在此类实例上传递一个方法,而无需覆盖酸洗辅助方法以排除pool 属性。但是对于实例可腌制的情况,这些方法是完全合法的; pool.apply_async('abc\r\n'.strip, ('a\n',)) 非常好,即使您传递的是方法,而不是函数。
猜你喜欢
  • 2016-04-18
  • 2012-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多