J'ai le code 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()
qui fonctionne bien. Cependant, MAX_PROCESSES
est variable et peut être n'importe quelle valeur comprise entre 1
et 512
. Étant donné que je n'exécute ce code que sur une machine avec des noyaux 8
, je dois savoir s'il est possible de limiter le nombre de processus autorisés à s'exécuter simultanément. J'ai examiné multiprocessing.Queue
, mais cela ne ressemble pas à ce dont j'ai besoin - ou j'interprète peut-être mal la documentation.
Est-il possible de limiter le nombre de multiprocessing.Process
s simultanés en cours d'exécution?
Il serait peut-être plus judicieux d'utiliser multiprocessing.Pool
, qui produit un pool de processus de travail basé sur le nombre maximal de cœurs disponibles sur votre système, puis d'alimenter les tâches au fur et à mesure que les cœurs deviennent disponibles.
L'exemple tiré de la documentation standard ( http://docs.python.org/2/library/multiprocessing.html#using-a-pool-of-workers ) montre que vous pouvez également définir manuellement le nombre de cœurs. :
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]"
Et il est également utile de savoir qu'il existe la méthode multiprocessing.cpu_count()
pour compter le nombre de cœurs sur un système donné, si nécessaire dans votre code.
Edit: Voici un projet de code qui semble fonctionner pour votre cas spécifique:
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()
plus généralement, cela pourrait aussi ressembler à ceci:
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()
Bien sûr, cette façon de faire est assez cruelle (car elle attend tous les processus dans une jonque avant de continuer avec le bloc suivant). Néanmoins, cela fonctionne bien pour des temps d’approximativement égaux aux appels de fonction.