Programmation multitâche en Python - partage de variables entre threads
Tags associés : 1. Renforcez votre Web avec Python
2. Shodan et l'API Python
import threading
g_num = 0
def task1 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK1:' , g_num )
def task2 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK2:' , g_num )
if __name__ == "__main__" :
first = threading.Thread ( target = task1 ) _ _
second = threading.Thread ( target = task2 ) _ _
first.start ( ) _
second.start ( ) _
En théorie, 1 million d'itérations sont exécutées et 1 est ajouté à la variable globale à chaque itération. Le résultat final devrait être 2 000 000. Le résultat réel est présenté plus haut.
Deux threads manipulent les variables globales simultanément. Lorsque le thread 1 lit la variable globale, le thread 2 la lit également. Lors d'une opération sur une variable, c'est la valeur originale qui est lue, et non la valeur modifiée. Le thread 1 n'ayant pas validé le résultat de son opération, le thread 2 a également lu la valeur précédente.
Solution
Utilisez la synchronisation de processus pour garantir qu'un seul thread manipule les données à la fois.
1. Utiliser la méthode join()
import threading
g_num = 0
def task1 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK1:' , g_num )
def task2 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK2:' , g_num )
if __name__ == "__main__" :
first = threading.Thread ( target = task1 ) _ _
second = threading.Thread ( target = task2 ) _ _
first.start ( ) _
first.join ( ) _
second.start ( ) _
Résultats :

Principe : la méthode first.join() met le programme en attente pendant l'exécution du premier thread. Le second thread ne démarre qu'une fois le premier terminé, ce qui garantit qu'un seul thread manipule la variable à la fois.
Synchronisation des threads : une tâche ne peut s'exécuter qu'après la fin de la précédente, de sorte qu'une seule tâche est en cours d'exécution à un instant donné.
2. Mutex
import threading
g_num = 0
# La création d'un mutex repose essentiellement sur une fonction via
LOCK = threading.Lock ( ) _
def task1 ():
# verrouillage
LOCK.acquire ( ) _
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK1:' , g_num )
# libération du verrou
LOCK.release ( ) _
def task2 ():
LOCK.acquire ( ) _
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK2:' , g_num )
LOCK.release ( ) _
if __name__ == "__main__" :
first = threading.Thread ( target = task1 ) _ _
second = threading.Thread ( target = task2 ) _ _
first.start ( ) _
second.start ( ) _
Principe : le verrouillage des données partagées garantit qu'un seul thread opère à la fois. Plusieurs threads tentent d'acquérir le verrou simultanément, et la fonction lock du module threading permet au premier arrivé de l'obtenir. Lors de l'exécution du premier thread, on verrouille le thread courant avec lock.acquire(), empêchant les autres threads de s'exécuter. Une fois la boucle terminée, lock.release() libère le thread courant, permettant aux autres threads d'opérer. Ainsi, un seul thread est actif à un instant donné.
Cependant, les verrous mutex affectent dans une certaine mesure l'efficacité du code, transformant le multitâche en exécution monotâche, et peuvent également provoquer des interblocages (causés par une libération tardive des verrous).
Déclaration de droits d'auteur : le contenu de cet article est fourni par des utilisateurs inscrits sous leur nom réel sur Alibaba Cloud. Les droits d'auteur appartiennent à l'auteur original. La communauté des développeurs Alibaba Cloud ne détient pas les droits d'auteur et n'assume pas la responsabilité juridique correspondante. Pour les règles détaillées, veuillez consulter l'« Accord de service utilisateur de la communauté des développeurs Alibaba Cloud » et les « Directives de protection de la propriété intellectuelle de la communauté des développeurs Alibaba Cloud ». Si vous trouvez du contenu suspecté de plagiat dans cette communauté, remplissez le formulaire de réclamation pour atteinte aux droits d'auteur. Une fois vérifié, la communauté supprimera immédiatement le contenu présumé contrefaisant.
2. Shodan et l'API Python
Problème : erreur de partage des données de variables globales entre threads
import threading
g_num = 0
def task1 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK1:' , g_num )
def task2 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK2:' , g_num )
if __name__ == "__main__" :
first = threading.Thread ( target = task1 ) _ _
second = threading.Thread ( target = task2 ) _ _
first.start ( ) _
second.start ( ) _
Résultat de l'opération :
En théorie, 1 million d'itérations sont exécutées et 1 est ajouté à la variable globale à chaque itération. Le résultat final devrait être 2 000 000. Le résultat réel est présenté plus haut.
Raison :
Deux threads manipulent les variables globales simultanément. Lorsque le thread 1 lit la variable globale, le thread 2 la lit également. Lors d'une opération sur une variable, c'est la valeur originale qui est lue, et non la valeur modifiée. Le thread 1 n'ayant pas validé le résultat de son opération, le thread 2 a également lu la valeur précédente.
Solution
Utilisez la synchronisation de processus pour garantir qu'un seul thread manipule les données à la fois.
1. Utiliser la méthode join()
import threading
g_num = 0
def task1 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK1:' , g_num )
def task2 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK2:' , g_num )
if __name__ == "__main__" :
first = threading.Thread ( target = task1 ) _ _
second = threading.Thread ( target = task2 ) _ _
first.start ( ) _
first.join ( ) _
second.start ( ) _
Résultats :

Principe : la méthode first.join() met le programme en attente pendant l'exécution du premier thread. Le second thread ne démarre qu'une fois le premier terminé, ce qui garantit qu'un seul thread manipule la variable à la fois.
Synchronisation des threads : une tâche ne peut s'exécuter qu'après la fin de la précédente, de sorte qu'une seule tâche est en cours d'exécution à un instant donné.
2. Mutex
import threading
g_num = 0
# La création d'un mutex repose essentiellement sur une fonction via
LOCK = threading.Lock ( ) _
def task1 ():
# verrouillage
LOCK.acquire ( ) _
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK1:' , g_num )
# libération du verrou
LOCK.release ( ) _
def task2 ():
LOCK.acquire ( ) _
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK2:' , g_num )
LOCK.release ( ) _
if __name__ == "__main__" :
first = threading.Thread ( target = task1 ) _ _
second = threading.Thread ( target = task2 ) _ _
first.start ( ) _
second.start ( ) _
Résultats :
Principe : le verrouillage des données partagées garantit qu'un seul thread opère à la fois. Plusieurs threads tentent d'acquérir le verrou simultanément, et la fonction lock du module threading permet au premier arrivé de l'obtenir. Lors de l'exécution du premier thread, on verrouille le thread courant avec lock.acquire(), empêchant les autres threads de s'exécuter. Une fois la boucle terminée, lock.release() libère le thread courant, permettant aux autres threads d'opérer. Ainsi, un seul thread est actif à un instant donné.
Cependant, les verrous mutex affectent dans une certaine mesure l'efficacité du code, transformant le multitâche en exécution monotâche, et peuvent également provoquer des interblocages (causés par une libération tardive des verrous).
Déclaration de droits d'auteur : le contenu de cet article est fourni par des utilisateurs inscrits sous leur nom réel sur Alibaba Cloud. Les droits d'auteur appartiennent à l'auteur original. La communauté des développeurs Alibaba Cloud ne détient pas les droits d'auteur et n'assume pas la responsabilité juridique correspondante. Pour les règles détaillées, veuillez consulter l'« Accord de service utilisateur de la communauté des développeurs Alibaba Cloud » et les « Directives de protection de la propriété intellectuelle de la communauté des développeurs Alibaba Cloud ». Si vous trouvez du contenu suspecté de plagiat dans cette communauté, remplissez le formulaire de réclamation pour atteinte aux droits d'auteur. Une fois vérifié, la communauté supprimera immédiatement le contenu présumé contrefaisant.
Articles connexes
-
6 technologies optionnelles pour le stockage de données
Équipe de la base de connaissances
Découvrir plus d'offres spéciales
-
Service de messages courts (SMS) et service de messagerie
50,000 email package starts as low as USD 1.99, 120 short messages start at only USD 1.00
