Synchronisation de plusieurs threads en python
-
23-08-2019 - |
Question
J'ai un problème où je dois threads x
attendre jusqu'à ce qu'ils aient tous atteint un point de synchronisation. Ma solution utilise la méthode synchronise
ci-dessous qui est appelé par chaque fonction filetée quand ils ont besoin de synchroniser.
Y at-il une meilleure façon de le faire?
thread_count = 0
semaphore = threading.Semaphore()
event = threading.Event()
def synchronise(count):
""" All calls to this method will block until the last (count) call is made """
with semaphore:
thread_count += 1
if thread_count == count:
event.set()
event.wait()
def threaded_function():
# Do something
# Block until 4 threads have reached this point
synchronise(4)
# Continue doing something else
La solution
Il y a plusieurs façons de synchroniser les threads. Beaucoup.
En plus de synchroniser, vous pouvez faire des choses comme ce qui suit.
-
Cassez vos tâches en deux étapes autour du point de synchronisation. threads commencer à faire de l'étape de pré-synchronisation. Ensuite, utilisez « join » attendre jusqu'à ce que toutes les discussions finissent l'étape 1. nouveaux sujets faisant l'étape de post-synchronisation. Je préfère cela, sur Synchronize.
-
Créer une file d'attente; acquérir un verrou de synchronisation. Démarrez toutes les discussions. Chaque thread met une entrée dans la file d'attente et attend le verrouillage de la synchronisation. Le fil « main » se trouve dans une boucle dequeueing d'articles dans la file d'attente. Lorsque toutes les discussions ont mis un élément dans la file d'attente, le thread « main » libère le verrou de synchronisation. Tous les autres threads sont maintenant libres de courir à nouveau.
Il y a un certain nombre de techniques de communication interprocessus (IPC) -. Qui peuvent tous être utilisés pour la synchronisation des threads
Autres conseils
La fonctionnalité que vous voulez est appelé "barrière ". (Malheureusement, ce terme a 2 significations quand on parle de filetage. Donc, si vous Google , juste ignorer les articles qui parlent de " barrières de mémoire . » - c'est une chose très différente)
Votre code semble tout à fait raisonnable - il est simple et sûre
.Je ne pouvais pas trouver « standard » implémentations de barrières pour Python, donc je vous suggère de continuer à utiliser votre code.
Notez que la barrière a été mis en œuvre à partir de Python 3.2
Exemple d'utilisation de barrières:
from threading import Barrier, Thread
def get_votes(site):
ballots = conduct_election(site)
all_polls_closed.wait() # do not count until all polls are closed
totals = summarize(ballots)
publish(site, totals)
all_polls_closed = Barrier(len(sites))
for site in sites:
Thread(target=get_votes, args=(site,)).start()