it-swarm.com.de

Verwenden von Multiprocessing.Prozess mit einer maximalen Anzahl gleichzeitiger Prozesse

Ich habe den Python Code:

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

das läuft gut. MAX_PROCESSES ist jedoch variabel und kann einen beliebigen Wert zwischen 1 und 512 haben. Da ich diesen Code nur auf einem Computer mit 8-Kernen ausführen möchte, muss ich herausfinden, ob es möglich ist, die Anzahl der Prozesse zu begrenzen, die gleichzeitig ausgeführt werden dürfen. Ich habe mir multiprocessing.Queue angesehen, aber es sieht nicht so aus, wie ich es brauche - oder vielleicht interpretiere ich die Dokumente falsch.

Gibt es eine Möglichkeit, die Anzahl der gleichzeitig ausgeführten multiprocessing.Processs zu begrenzen?

47
Brett

Es ist möglicherweise am sinnvollsten, multiprocessing.Pool zu verwenden, der einen Pool von Arbeitsprozessen auf der Grundlage der maximalen Anzahl von Kernen erstellt, die in Ihrem System verfügbar sind. Anschließend werden im Wesentlichen Aufgaben eingespeist, sobald die Kerne verfügbar werden.

Das Beispiel aus den Standarddokumenten ( http://docs.python.org/2/library/multiprocessing.html#using-a-pool-of-workers ) zeigt, dass Sie die Anzahl der Kerne auch manuell einstellen können :

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]"

Und es ist auch praktisch zu wissen, dass es die multiprocessing.cpu_count()-Methode gibt, um die Anzahl der Kerne eines bestimmten Systems zu zählen, falls dies in Ihrem Code erforderlich ist.

Bearbeiten: Hier ist ein Entwurfscode, der in Ihrem speziellen Fall zu funktionieren scheint:

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

allgemeiner könnte dies auch so aussehen:

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

Natürlich ist dieser Weg ziemlich grausam (da er auf jeden Prozess in einem Müll wartet, bis er mit dem nächsten Block weitergeht). Trotzdem funktioniert es gut für ungefähr gleiche Laufzeiten der Funktionsaufrufe.

0
Baedsch