如何将队列引用传递给pool.map_async()管理的函数?

时间:2010-07-09 22:42:09

标签: python queue multiprocessing pool

我想要一个长时间运行的进程来返回它在队列(或类似的东西)上的进度,我将把它提供给进度条对话框。完成该过程后,我还需要结果。此处的测试示例失败,并显示RuntimeError: Queue objects should only be shared between processes through inheritance

import multiprocessing, time

def task(args):
    count = args[0]
    queue = args[1]
    for i in xrange(count):
        queue.put("%d mississippi" % i)
    return "Done"

def main():
    q = multiprocessing.Queue()
    pool = multiprocessing.Pool()
    result = pool.map_async(task, [(x, q) for x in range(10)])
    time.sleep(1)
    while not q.empty():
        print q.get()
    print result.get()

if __name__ == "__main__":
    main()

我已经能够使用单个Process对象(我通过队列引用)来使用它,但后来我没有池来管理多个进程想要发布。有关更好的模式的建议吗?

2 个答案:

答案 0 :(得分:44)

以下代码似乎有效:

import multiprocessing, time

def task(args):
    count = args[0]
    queue = args[1]
    for i in xrange(count):
        queue.put("%d mississippi" % i)
    return "Done"


def main():
    manager = multiprocessing.Manager()
    q = manager.Queue()
    pool = multiprocessing.Pool()
    result = pool.map_async(task, [(x, q) for x in range(10)])
    time.sleep(1)
    while not q.empty():
        print q.get()
    print result.get()

if __name__ == "__main__":
    main()

请注意,Queue来自manager.Queue()而不是multiprocessing.Queue()。谢谢亚历克斯指点我这个方向。

答案 1 :(得分:8)

使q 全球有效......:

import multiprocessing, time

q = multiprocessing.Queue()

def task(count):
    for i in xrange(count):
        q.put("%d mississippi" % i)
    return "Done"

def main():
    pool = multiprocessing.Pool()
    result = pool.map_async(task, range(10))
    time.sleep(1)
    while not q.empty():
        print q.get()
    print result.get()

if __name__ == "__main__":
    main()

如果您需要多个队列,例如为了避免混淆各种池进程的进度,全局队列列表应该工作(当然,每个进程都需要知道要使用的列表中的 index ,但是可以通过作为一个论点; - )。