2017-10-13 3 views
0

J'ai un thread d'arrière-plan que les appels principaux, le thread d'arrière-plan peut ouvrir un certain nombre de scripts différents, mais parfois il obtiendra une boucle d'impression infinie comme ceci.Obtenir un thread pour quitter une boucle infinie (intentionnelle)?

Dans thing.py import foo

def main(): 
    thr = Thread(target=background) 
    thr.start() 
    thread_list.append(thr) 

def background(): 
    getattr(foo, 'bar')() 
    return 

Et puis dans foo.py

def bar(): 
    while True: 
     print("stuff") 

C'est ce qu'il est censé faire, mais je veux être en mesure de le tuer quand je dois. Y a-t-il un moyen pour moi de tuer le thread d'arrière-plan et toutes les fonctions qu'il a appelé? J'ai essayé de mettre des drapeaux dans background pour renvoyer quand le drapeau devient haut, mais background n'est jamais capable de vérifier les drapeaux puisqu'il attend bar pour retourner.

EDIT: foo.py est mon code, donc je suis hésité à le modifier, idéalement, je pouvais le faire sans modifier foo.py mais s'il est impossible d'éviter son accord

+0

Copie possible de [Comment arrêter un thread en boucle en Python?] (Https://stackoverflow.com/questions/18018033/how-to-stop-a-looping-thread-in-python) – harandk

Répondre

1

Tout d'abord, il est très difficile (si possible) de contrôler les threads d'autres threads, quelle que soit la langue que vous utilisez. Cela est dû à des problèmes de sécurité potentiels. Donc ce que vous faites est de créer un objet partagé auquel les deux threads peuvent accéder librement. Vous pouvez définir un drapeau dessus.

Mais heureusement en Python chaque thread a son propre objet Thread que nous pouvons utiliser:

import foo 

def main(): 
    thr = Thread(target=background) 
    thr.exit_requested = False 
    thr.start() 
    thread_list.append(thr) 

def background(): 
    getattr(foo, 'bar')() 
    return 

Et dans foo:

import threading 

def bar(): 
    th = threading.current_thread() 
    # What happens when bar() is called from the main thread? 
    # The commented code is not thread safe. 
    # if not hasattr(th, 'exit_requested'): 
    #  th.exit_requested = False 
    while not th.exit_requested: 
     print("stuff") 

Bien que ce sera probablement difficile à maintenir/debug. Traitez-le plus comme un hack. Une manière plus simple serait de créer un objet partagé et de le transmettre à tous les appels.

+0

Merci. Cela vous dérange-t-il d'expliquer d'où vient thread.current_thread() et comment passer le thr.exit_requested à un autre fichier? J'ai essayé d'implémenter ce code et je ne peux pas tout à fait le faire fonctionner – Indigo

+0

@Indigo Mon mauvais, c'était une faute de frappe. J'ai mis à jour le code (vous avez besoin de 'importer le filetage '). Aussi 'exit_requested' est défini dans' main'. – freakish