2010-01-07 19 views
2

J'ai un tableau de discussions. Chacun d'eux appelle la méthode run en continu. À la fin de chaque méthode d'exécution, je veux qu'ils fassent une pause et attendent.Thread Python Pause et attendre

Comment puis-je obtenir les threads à exécuter un à la fois, puis continuer la boucle lorsque tous sont terminés? J'ai besoin qu'ils s'exécutent TOUJOURS dans l'ordre (ie: 1, 2, 3, 4 - 1, 2, 3, 4 ...)

J'utilise actuellement threading.Event, mais les résultats sont incohérents.

Merci

MISE À JOUR

Merci à tous pour vos réponses à ce jour. J'écris quelque chose de similaire à Robocode en python. Les joueurs programment un bot et les bots s'affrontent jusqu'à ce qu'il en reste un. Après chaque "tour", les robots sont "en pause" puis mis à jour et attirés vers l'écran. Ensuite, ils commencent tous un nouveau tour.

Exemple:

# Bot extends threading.Thread 
class DemoBot(Bot): 
    def __init__(self): 
     super(DemoBot, self).__init__() 

    def run(self): 
     while True: 
      self.moveForward(100) 
      self.turnLeft(90) 

Comme vous pouvez le voir, le robot est dans une boucle infinie. Dans la méthode moveForward, le robot avance de 100px. Mais afin de mettre à jour l'écran correctement, je dois me déplacer une fois, mettre en pause, mettre à jour, puis déplacer à nouveau. C'est pourquoi je dois être en mesure de "mettre en pause" un robot une fois qu'il est terminé et que le programme attende les autres avant de mettre à jour l'écran.

Espérons que cela a un peu plus de sens.

+7

Si vous avez besoin de les exécuter séquentiellement, alors pourquoi utilisez-vous plusieurs threads? –

+1

Peut-être en disant «ce que vous essayez d'atteindre» apportera de meilleures réponses –

Répondre

0

peut-être quelque chose comme

while True: 
    list = [] 
    for i in xrange(100): 
    t = myThread(data[i]) 
    list.append(t) 
    t.start() 
    for t in list: t.join() 
3

Votre description semble que vous ne voulez pas entendre les fils d'exécuter en même temps, ce qui remettrait en question la raison pour laquelle vous utilisez le filetage en premier lieu.

Je sens deux réponses possibles à la question de savoir pourquoi vous voudriez faire cela. La première possibilité est que vous essayez d'empêcher vos threads de travailler sur une sorte de ressource partagée en même temps. Si c'est le cas, vous voudrez probablement utiliser threading.Lock ou threading.RLock pour verrouiller votre section de code critique. (L'exemple ci-dessous est codé pour python 2.5+, vous aurez besoin d'utiliser de verrouillage explicite acquérir/libération sur pythons âgées)

from __future__ import with_statement # only needed on python 2.5 
from threading import Lock 
lock = Lock() 


def worker1(): 
    #noncritical code 
    with lock: 
     pass # critical code in here 

def worker2(): 
    with lock: 
     critical_code 

Cela n'appliquera toute sorte de commande, cependant. Lorsque plusieurs threads tentent d'acquérir un verrou, tous sauf un bloquent (et celui qui acquiert le verrou suivant n'est pas déterminé)

Le fait que vous ayez mentionné la commande me fait penser que vous avez plutôt une sorte de cycle producteur-consommateur sur. C'est-à-dire qu'un thread génère une sortie avec laquelle le prochain doit travailler. Vous pouvez utiliser queue.Queue pour fournir des données entre les threads et les faire se réveiller pour engloutir le bit de données suivant.

from queue import Queue 

one_to_two = Queue(maxsize=10)  

def worker1(): 
    while i_have_some_data_stream: 
     data = get_data_from_somewhere() 
     modified_data = munge_data_somehow(data) 
     one_to_two.put(modified_data) #blocks only if queue is currently full 

def worker2(): 
    while True: 
     data = one_to_two.get() # blocks until data available 
     # do something with data 
     # Optionally, put this newly processed data into the next queue. 

Les files d'attente sont une primitive puissante qui vous permet de transmettre des messages entre threads et d'implémenter des producteurs-consommateurs bornés. Si c'est votre cas d'utilisation, la file d'attente sera plus efficace que d'essayer de synchroniser manuellement la commande de votre thread.

+0

Merci pour les informations détaillées Crast. Avez-vous d'autres commentaires basés sur ma mise à jour? Suggéreriez-vous toujours d'utiliser Queue? –

+0

Non, il semble que vous voulez probablement une sorte de verrouillage. Il semble que la section de mise à jour de l'écran est votre section de code critique, et selon la façon dont vous voulez que les choses fonctionnent, vous voudrez verrouiller la section où vous dessinez le mouvement du bot (éventuellement à chaque itération de la boucle, ou moveForward.) Cela dépend. Ensuite, pour synchroniser tous les threads à la fin de chaque tour, vous pouvez utiliser un 'threading.Condition' qui vous permettra de tous les attendre jusqu'à ce que le maître signale qu'il est temps de reprendre. – Crast

Questions connexes