web-dev-qa-db-ja.com

最大数の同時プロセスでmultiprocessing.Processを使用する

私はPythonコードを持っています:

from multiprocessing import Process

def f(name):
    print 'hello', name

if __== '__main__':
    for i in range(0, MAX_PROCESSES):
        p = Process(target=f, args=(i,))
        p.start()

うまく動作します。ただし、MAX_PROCESSESは可変であり、1512の間の任意の値にできます。このコードは8コアのマシンでのみ実行しているため、同時に実行できるプロセスの数を制限できるかどうかを調べる必要があります。 multiprocessing.Queueを調べましたが、必要なものに見えません-またはドキュメントを誤って解釈している可能性があります。

同時に実行されるmultiprocessing.Processsの数を制限する方法はありますか?

53
Brett

システムで使用可能なコアの最大数に基づいてワーカープロセスのプールを生成し、基本的にコアが使用可能になるとタスクをフィードする_multiprocessing.Pool_を使用するのが最も賢明かもしれません。

標準ドキュメントの例( http://docs.python.org/2/library/multiprocessing.html#using-a-pool-of-workers )は、手動で設定することもできることを示していますコアの数:

_from multiprocessing import Pool

def f(x):
    return x*x

if __== '__main__':
    pool = Pool(processes=4)              # start 4 worker processes
    result = pool.apply_async(f, [10])    # evaluate "f(10)" asynchronously
    print result.get(timeout=1)           # prints "100" unless your computer is *very* slow
    print pool.map(f, range(10))          # prints "[0, 1, 4,..., 81]"
_

また、コードで必要に応じて、特定のシステムのコア数をカウントするmultiprocessing.cpu_count()メソッドがあることを知っておくと便利です。

編集:特定のケースで機能すると思われるドラフトコードを次に示します。

_import multiprocessing

def f(name):
    print 'hello', name

if __== '__main__':
    pool = multiprocessing.Pool() #use all available cores, otherwise specify the number you want as an argument
    for i in xrange(0, 512):
        pool.apply_async(f, args=(i,))
    pool.close()
    pool.join()
_
78
treddy

より一般的には、これは次のようにもなります。

import multiprocessing
def chunks(l, n):
    for i in range(0, len(l), n):
        yield l[i:i + n]

numberOfThreads = 4


if __== '__main__':
    jobs = []
    for i, param in enumerate(params):
        p = multiprocessing.Process(target=f, args=(i,param))
        jobs.append(p)
    for i in chunks(jobs,numberOfThreads):
        for j in i:
            j.start()
        for j in i:
            j.join()

もちろん、その方法は非常に残酷です(ジャンク内のすべてのプロセスが次のチャンクに続くまで待機するため)。それでも、関数呼び出しの実行時間がほぼ等しい場合はうまく機能します。

2
Baedsch