42

我想要一个长时间运行的进程通过队列(或类似的东西)返回它的进度,我将把它提供给进度条对话框。当过程完成时,我还需要结果。此处的测试示例以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 对象(我可以在其中传递Queue 引用)让它工作,但是我没有一个池来管理我想要启动的许多进程。对此有更好的模式有什么建议吗?

4

2 回答 2

56

以下代码似乎有效:

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()

请注意,队列来自 manager.Queue() 而不是 multiprocessing.Queue()。感谢 Alex 为我指明了这个方向。

于 2010-07-12T20:30:58.010 回答
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()

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

于 2010-07-10T01:26:57.393 回答