Supposons que j'ai les éléments suivants en Python
# A loop
for i in range(10000):
Do Task A
# B loop
for i in range(10000):
Do Task B
Comment puis-je exécuter ces boucles simultanément en Python?
Si vous voulez la concurrence, voici un exemple très simple:
from multiprocessing import Process
def loop_a():
while 1:
print("a")
def loop_b():
while 1:
print("b")
if __== '__main__':
Process(target=loop_a).start()
Process(target=loop_b).start()
Ceci est juste le exemple le plus fondamental auquel je pourrais penser. Assurez-vous de lire http://docs.python.org/library/multiprocessing.html pour comprendre ce qui se passe.
Si vous souhaitez renvoyer des données au programme, je vous recommande d'utiliser une file d'attente (qui, d'après mon expérience, est la plus simple à utiliser).
Vous pouvez utiliser un fil à la place si vous ne vous souciez pas du verrou d'interprète global . Les processus sont plus coûteux à instancier, mais ils offrent une vraie concurrence.
Pourquoi voulez-vous exécuter les deux processus en même temps? Est-ce parce que vous pensez qu'ils iront plus vite (il y a de bonnes chances qu'ils ne le fassent pas). Pourquoi ne pas exécuter les tâches dans la même boucle, par exemple.
for i in range(10000):
doTaskA()
doTaskB()
La réponse évidente à votre question est d’utiliser des threads - voir le module python threading . Cependant, le filetage est un gros sujet et comporte de nombreux pièges, lisez-le avant de vous lancer dans cette voie.
Sinon, vous pouvez exécuter les tâches dans des processus distincts, en utilisant le module python multiprocessing . Si les deux tâches consomment beaucoup de ressources en processeur, cela permettra de mieux utiliser plusieurs cœurs sur votre ordinateur.
Il existe d'autres options telles que des routines, des tâches sans pile, des greenlets, des CSP, etc., mais sans en savoir plus sur les tâches A et B et sur la raison pour laquelle elles doivent être exécutées en même temps, il est impossible de donner une réponse plus précise.
Il y a beaucoup d'options possibles pour ce que vous vouliez:
Comme beaucoup de gens l’ont souligné, c’est le moyen le plus simple.
for i in xrange(10000):
# use xrange instead of range
taskA()
taskB()
Mérites: facile à comprendre et à utiliser, aucune bibliothèque supplémentaire nécessaire.
Inconvénients: taskB doit être effectué après taskA ou autrement. Ils ne peuvent pas fonctionner simultanément.
Une autre idée serait: exécutez deux processus en même temps, Python fournit une bibliothèque multi-processus , voici un exemple simple:
from multiprocessing import Process
p1 = Process(target=taskA, args=(*args, **kwargs))
p2 = Process(target=taskB, args=(*args, **kwargs))
p1.start()
p2.start()
mérite: la tâche peut être exécutée simultaneously
en arrière-plan, vous pouvez contrôler les tâches (les arrêter, les arrêter, etc.), les tâches peuvent échanger des données, peuvent être synchronisées si elles mettent en concurrence les mêmes ressources, etc.
inconvénients: trop lourd! Les systèmes d’exploitation basculent fréquemment entre eux, ils disposent de leur propre espace de données, même si les données sont redondantes. Si vous avez beaucoup de tâches (disons 100 ou plus), ce n'est pas ce que vous voulez.
le filetage est comme un processus, juste léger. Découvrez ce post . Leur utilisation est assez similaire:
import threading
p1 = threading.Thread(target=taskA, args=(*args, **kwargs))
p2 = threading.Thread(target=taskB, args=(*args, **kwargs))
p1.start()
p2.start()
des bibliothèques telles que greenlet
et gevent
fournissent quelque chose appelé coroutines, censé être plus rapide que le threading. Aucun exemple fourni, s'il vous plaît google comment les utiliser si cela vous intéresse.
mérites: plus souple et léger
inconvénients: bibliothèque supplémentaire nécessaire, courbe d'apprentissage.
from threading import Thread
def loopA():
for i in range(10000):
#Do task A
def loopB():
for i in range(10000):
#Do task B
threadA = Thread(target = loopA)
threadB = Thread(target = loobB)
threadA.run()
threadB.run()
# Do work indepedent of loopA and loopB
threadA.join()
threadB.join()
Que diriez-vous: d'une boucle pour i dans la plage (10000): effectuez la tâche A, effectuez-vous la tâche B? Sans plus d'informations, je n'ai pas de meilleure réponse.
Vous pouvez utiliser threading ou multitraitement .
Je trouve que l'utilisation du sous-module "pool" dans "multitraitement" fonctionne à merveille pour l'exécution de plusieurs processus simultanément dans un script Python.
Voir section: Utilisation d'un bassin de travailleurs
Regardez attentivement "# lancer plusieurs évaluations de manière asynchrone may utiliser plus de processus" dans l'exemple. Une fois que vous avez compris ce que font ces lignes, l’exemple suivant que j’ai construit aura beaucoup de sens.
import numpy as np
from multiprocessing import Pool
def desired_function(option, processes, data, etc...):
# your code will go here. option allows you to make choices within your script
# to execute desired sections of code for each pool or subprocess.
return result_array # "for example"
result_array = np.zeros("some shape") # This is normally populated by 1 loop, lets try 4.
processes = 4
pool = Pool(processes=processes)
args = (processes, data, etc...) # Arguments to be passed into desired function.
multiple_results = []
for i in range(processes): # Executes each pool w/ option (1-4 in this case).
multiple_results.append(pool.apply_async(param_process, (i+1,)+args)) # Syncs each.
results = np.array(res.get() for res in multiple_results) # Retrieves results after
# every pool is finished!
for i in range(processes):
result_array = result_array + results[i] # Combines all datasets!
Le code exécutera la fonction souhaitée pour un nombre défini de processus. Vous devrez vous assurer avec soin que votre fonction peut faire la distinction entre chaque processus (d'où la raison pour laquelle j'ai ajouté la variable "option".) De plus, il ne doit pas nécessairement s'agir d'un tableau qui est rempli à la fin, mais pour mon exemple, c'est comme ça que je l'ai utilisé. J'espère que cela simplifie ou vous aide à mieux comprendre la puissance du multitraitement en Python!