web-dev-qa-db-ja.com

Pool.imapによって呼び出される関数でマルチプロセッシングキューを使用できますか?

python 2.7を使用していて、CPUの負荷の高いタスクを独自のプロセスで実行しようとしています。親プロセスにメッセージを返送して、現在のプロセスを常に通知できるようにしたいと思います。プロセスのステータス。マルチプロセッシングキューはこれに最適のようですが、それを機能させる方法がわかりません。

したがって、これは私の基本的な作業例からキューの使用を除いたものです。

import multiprocessing as mp
import time

def f(x):
    return x*x

def main():
    pool = mp.Pool()
    results = pool.imap_unordered(f, range(1, 6))
    time.sleep(1)

    print str(results.next())

    pool.close()
    pool.join()

if __name__ == '__main__':
    main()

いくつかの方法でキューを渡そうとしましたが、「RuntimeError:キューオブジェクトは継承を通じてプロセス間でのみ共有する必要があります」というエラーメッセージが表示されます。これは私が見つけた以前の答えに基づいて私が試した方法の1つです。 (Pool.map_asyncとPool.imapを使用しようとすると同じ問題が発生します)

import multiprocessing as mp
import time

def f(args):
    x = args[0]
    q = args[1]
    q.put(str(x))
    time.sleep(0.1)
    return x*x

def main():
    q = mp.Queue()
    pool = mp.Pool()
    results = pool.imap_unordered(f, ([i, q] for i in range(1, 6)))

    print str(q.get())

    pool.close()
    pool.join()

if __name__ == '__main__':
    main()

最後に、0フィットネスアプローチ(グローバルにする)はメッセージを生成せず、ロックするだけです。

import multiprocessing as mp
import time

q = mp.Queue()

def f(x):
    q.put(str(x))
    return x*x

def main():
    pool = mp.Pool()
    results = pool.imap_unordered(f, range(1, 6))
    time.sleep(1)

    print q.get()

    pool.close()
    pool.join()

if __name__ == '__main__':
    main()

おそらくmultiprocessing.Processで直接動作し、これを実現する他のライブラリがあることは承知していますが、自分の不足だけではないと確信するまで、最適な標準ライブラリ関数から離れることは嫌です。私がそれらを利用することができないようにする知識の。

ありがとう。

26
Olson

秘訣は、キューを引数として初期化子に渡すことです。すべてのプールディスパッチ方法で機能するように見えます。

import multiprocessing as mp

def f(x):
    f.q.put('Doing: ' + str(x))
    return x*x

def f_init(q):
    f.q = q

def main():
    jobs = range(1,6)

    q = mp.Queue()
    p = mp.Pool(None, f_init, [q])
    results = p.imap(f, jobs)
    p.close()

    for i in range(len(jobs)):
        print q.get()
        print results.next()

if __name__ == '__main__':
    main()
46
Olson