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
Était-ce utile?

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.

  1. 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.

  2. 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()
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top