web-dev-qa-db-ja.com

Queue参照をpool.map_async()が管理する関数にどのように渡しますか?

実行時間の長いプロセスがキュー(または同様のもの)を介して進行状況を返し、それをプログレスバーダイアログにフィードします。プロセスが完了したときの結果も必要です。ここでのテスト例は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()

個別のプロセスオブジェクトを使用してこれを機能させることができましたが(キュー参照を渡すのにamが遅くなっています)、起動する多くのプロセスを管理するプールがありません。このためのより良いパターンについてアドバイスはありますか?

39
David

次のコードは動作するようです:

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はmultiprocessing.Queue()ではなくmanager.Queue()から取得されることに注意してください。アレックス、私をこの方向に向けてくれてありがとう。

50
David

qglobalを機能させる...:

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を知る必要がありますが、渡すことは問題ありません)引数として;-)。

7
Alex Martelli