Question

J'ai un fil qui ajoute des lignes à self.output et une boucle qui s'exécute jusqu'à ce que self.done devienne True (ou que le temps d'exécution maximal soit atteint).

Existe-t-il un moyen plus efficace de procéder ainsi que d'utiliser une boucle while vérifiant en permanence si cela est fait? La boucle while provoque un pic de 100% du processeur pendant son exécution.

time.clock()
while True:

    if len(self.output):
        yield self.output.pop(0)

    elif self.done or 15 < time.clock():
        if 15 < time.clock():
            yield "Maximum Execution Time Exceeded %s seconds" % time.clock()
        break
Était-ce utile?

La solution

Vos discussions sont-elles ajoutées à self.output ici, avec la tâche principale qui les consomme? Si tel est le cas, il s'agit d'un travail sur mesure pour Queue.Queue . Votre code devrait devenir quelque chose comme:

import Queue

# Initialise queue as:
queue = Queue.Queue()
Finished = object()   # Unique marker the producer will put in the queue when finished

# Consumer:
try:
    while True:
        next_item = self.queue.get(timeout=15)
        if next_item is Finished: break
        yield next_item

except Queue.Empty:
    print "Timeout exceeded"

Vos threads producteurs ajoutent des éléments à la file d'attente avec queue.put (élément)

[Éditer] Le code d'origine a un problème de course lors de la vérification de self.done (par exemple, plusieurs éléments peuvent être ajoutés à la file d'attente avant que le drapeau ne soit défini, ce qui provoque la sauvegarde du code à la fin du processus. Premier). Mis à jour avec une suggestion de & # 932; & # 918; & # 937; & # 932; & # 918; & # 921; & # 927; & # 933; & # 933; - le thread producteur devrait plutôt ajouter un jeton spécial (Terminé) à la file d'attente pour indiquer qu'il est terminé.

Remarque: si vous avez plusieurs threads de production, vous aurez besoin d’une approche plus générale pour détecter leur fin. Vous pouvez accomplir cela avec la même stratégie: chaque thread est un marqueur Terminé et le consommateur se termine lorsqu'il voit les marqueurs num_threads.

Autres conseils

Utilisez un sémaphore; demandez au thread de travail de le relâcher quand il a terminé et de bloquer votre thread ajouté jusqu'à ce que l'ouvrier ait terminé d'utiliser le sémaphore.

c'est à dire. dans le travailleur, faites quelque chose comme self.done = threading.Semaphore () au début du travail et self.done.release () à la fin. Dans le code que vous avez noté ci-dessus, au lieu de la boucle occupée, faites simplement self.done.acquire () ; lorsque le thread de travail est terminé, le contrôle retourne.

Edit: J'ai bien peur de ne pas aborder la valeur de délai d'expiration dont vous avez besoin; Ce numéro décrit la nécessité d'un délai d'expiration du sémaphore dans la bibliothèque standard.

Utilisez time.sleep (secondes) pour créer une brève pause après chaque itération de la boucle while afin d'abandonner le processeur. Vous devrez définir l'heure de votre sommeil à chaque itération en fonction de l'importance de saisir le travail rapidement après son achèvement.

Exemple:

time.clock()
while True:

    if len(self.output):
        yield self.output.pop(0)

    elif self.done or 15 < time.clock():
        if 15 < time.clock():
            yield "Maximum Execution Time Exceeded %s seconds" % time.clock()
            break

    time.sleep(0.01) # sleep for 10 milliseconds

utiliser un module mutex ou un événement / sémaphore

Vous devez utiliser une primitive de synchronisation ici. Regardez ici: http://docs.python.org/library/threading.html .

Les objets d'événement semblent très simples et devraient résoudre votre problème. Vous pouvez également utiliser un objet de condition ou un sémaphore.

Je ne poste pas d'exemple car je n'ai jamais utilisé d'objets Event, et les alternatives sont probablement moins simples.

Modifier: je ne suis pas sûr d'avoir compris votre problème. Si un thread peut attendre qu'une condition soit remplie, utilisez la synchronisation. Sinon, la solution sleep () proposée par quelqu'un postulera au sujet de prendre un temps processeur trop important.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top