Je voudrais contribuer avec un exemple simple et les explications que j'ai trouvées utiles lorsque j'ai dû résoudre ce problème moi-même.
Dans cette réponse, vous trouverez des informations sur le GIL de Python (verrouillage de l'interpréteur global) et un exemple simple écrit au jour le jour à l'aide de multiprocessing.dummy ainsi que quelques tests de référence simples.
Verrou d'interprète global (GIL)
Python n'autorise pas le multi-threading dans le vrai sens du mot. Il a un package multi-thread, mais si vous voulez multi-thread pour accélérer votre code, ce n'est généralement pas une bonne idée de l'utiliser.
Python a une construction appelée le verrou d'interpréteur global (GIL). Le GIL s'assure qu'un seul de vos «threads» peut s'exécuter à la fois. Un thread acquiert le GIL, fait un petit travail, puis passe le GIL sur le thread suivant.
Cela se produit très rapidement, donc à l'œil humain, il peut sembler que vos threads s'exécutent en parallèle, mais ils se tournent vraiment à tour de rôle en utilisant le même cœur de processeur.
Tout ce passage GIL ajoute des frais généraux à l'exécution. Cela signifie que si vous souhaitez accélérer l'exécution de votre code, l'utilisation du package de thread n'est souvent pas une bonne idée.
Il y a des raisons d'utiliser le package de threads de Python. Si vous voulez exécuter certaines choses simultanément et que l'efficacité n'est pas un problème, c'est tout à fait correct et pratique. Ou si vous exécutez du code qui doit attendre quelque chose (comme des E / S), cela peut avoir beaucoup de sens. Mais la bibliothèque de threads ne vous permettra pas d'utiliser des cœurs de processeur supplémentaires.
Le multi-threading peut être externalisé vers le système d'exploitation (en effectuant le multi-traitement) et une application externe qui appelle votre code Python (par exemple, Spark ou Hadoop ), ou du code que votre code Python appelle (par exemple: vous pourriez demandez à votre code Python d'appeler une fonction C qui fait les choses coûteuses multi-thread).
Pourquoi c'est important
Parce que beaucoup de gens passent beaucoup de temps à essayer de trouver des goulots d'étranglement dans leur code multi-thread Python avant d'apprendre ce qu'est le GIL.
Une fois ces informations claires, voici mon code:
#!/bin/python
from multiprocessing.dummy import Pool
from subprocess import PIPE,Popen
import time
import os
# In the variable pool_size we define the "parallelness".
# For CPU-bound tasks, it doesn't make sense to create more Pool processes
# than you have cores to run them on.
#
# On the other hand, if you are using I/O-bound tasks, it may make sense
# to create a quite a few more Pool processes than cores, since the processes
# will probably spend most their time blocked (waiting for I/O to complete).
pool_size = 8
def do_ping(ip):
if os.name == 'nt':
print ("Using Windows Ping to " + ip)
proc = Popen(['ping', ip], stdout=PIPE)
return proc.communicate()[0]
else:
print ("Using Linux / Unix Ping to " + ip)
proc = Popen(['ping', ip, '-c', '4'], stdout=PIPE)
return proc.communicate()[0]
os.system('cls' if os.name=='nt' else 'clear')
print ("Running using threads\n")
start_time = time.time()
pool = Pool(pool_size)
website_names = ["www.google.com","www.facebook.com","www.pinterest.com","www.microsoft.com"]
result = {}
for website_name in website_names:
result[website_name] = pool.apply_async(do_ping, args=(website_name,))
pool.close()
pool.join()
print ("\n--- Execution took {} seconds ---".format((time.time() - start_time)))
# Now we do the same without threading, just to compare time
print ("\nRunning NOT using threads\n")
start_time = time.time()
for website_name in website_names:
do_ping(website_name)
print ("\n--- Execution took {} seconds ---".format((time.time() - start_time)))
# Here's one way to print the final output from the threads
output = {}
for key, value in result.items():
output[key] = value.get()
print ("\nOutput aggregated in a Dictionary:")
print (output)
print ("\n")
print ("\nPretty printed output: ")
for key, value in output.items():
print (key + "\n")
print (value)