2011-02-16 1 views
3

Possible en double:
Is there any way to kill a Thread in Python?Python: Comment mettre fin à un fil de blocage

Donc, cette question fait suite à une solution tition. Fondamentalement, il s'agit de mettre fin à un fil par programmation: http://sebulba.wikispaces.com/recipe+thread2

Cependant, cela ne fonctionne pas ... et je me demandais si quelqu'un peut expliquer comment on pourrait terminer un thread qui bloque? Ma seule supposition est le fait que je ne fournis pas le bon identifiant de thread, mais j'ai fait quelques tests et je suis sûr que je peux juste utiliser iden

S'il s'agit de l'ID de thread, comment puis-je obtenir le bon thread ID?

Code d'essai:

class BlockingTestThread(Thread): 

    def __init__(self): 
     self._running_flag = False 
     Thread.__init__(self, target=self.test_method) 

    def test_method(self): 
     try: 
      while(not self.stopped()): 
       self._running_flag = True 
       time.sleep(100) 
     finally: 
       self._running_flag = False 


def _async_raise(tid, exctype): 
    '''Raises an exception in the threads with id tid''' 
    if not inspect.isclass(exctype): 
     raise TypeError("Only types can be raised (not instances)") 

    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), ctypes.py_object(exctype)) 
    time.sleep(0.1) 



if __name__ == "__main__": 
    thread = BlockingTestThread() 
    thread.start() 

    _async_raise(thread.ident, SystemExit) 
    print "Joining thread" 
    thread.join() 
    print "Done Joining thread" 
    #will never get here! 
+0

BTW, mon hack autour était d'interup la connexion que le récepteur écoutait, je fondamentalement puis juste l'attraper et quitter la boucle. C'est moche, mais je ne peux pas trouver un autre moyen. – Nix

+0

Acceptez-vous que c'est un doublon? –

Répondre

4

Voici une meilleure façon de le faire, utilisez la commande "wait" de l'événement, en supposant que vous voulez utiliser sleep.

class BlockingTestThread(Thread): 
    def __init__(self): 
     self._running_flag = False 
     self.stop = threading.Event() 
     Thread.__init__(self, target=self.test_method) 

    def test_method(self): 
     try: 
      while(not self.stop.wait(1)): 
       self._running_flag = True 
       print 'Start wait' 
       self.stop.wait(100) 
       print 'Done waiting' 
     finally: 
       self._running_flag = False 

    def terminate(self): 
     self.stop.set() 

if __name__ == "__main__": 
    thread = BlockingTestThread() 
    thread.start() 

    time.sleep(2) 
    print 'Time sleep 2' 
    thread.terminate() 
    print "Joining thread" 
    thread.join() 
    print "Done Joining thread" 

Il est évident que vous allez avoir besoin d'envelopper votre fil de blocage dans quelque chose qui utilise le schéma ci-dessus, mais si vous ne pouvez pas l'autre option est de provoquer votre processus de lancer une exception, dans notre cas, nous en gros tuez la connexion sous-jacente, ce qui provoque une exception, et lorsque cette exception se produit si le drapeau arrêté est activé, nous l'ignorons.

0

Vous avez raison sur ident, de la documentation, la variable ident ne correspond pas à TID, il est juste un référence-

thread.get_ident (

Renvoie le 'identificateur de thread' du thread en cours. C'est un entier différent de zéro. Sa valeur n'a pas de signification directe; il est conçu comme un cookie magique à utiliser par exemple. indexer un dictionnaire de données spécifiques au thread. Les identifiants de threads peuvent être recyclés lorsqu'un thread se termine et qu'un autre thread est créé.

Voir http://bytes.com/topic/python/answers/45247-terminating-thread-parent re: killling, je ne sais pas si c'est exactement ce que vous cherchez malheureusement.

+0

Cet exemple ne bloque pas .... Je suppose que ce n'est pas possible ... – Nix