2010-04-06 4 views
0

Je n'arrive pas à terminer un thread suspendu dans un appel socket.recvfrom(). Par exemple, ctrl + c qui doit déclencher une exception KeyboardInterrupt ne peut pas être interceptée. Voici un script que je l'ai utilisé pour les tests:python: impossible de terminer un thread bloqué dans l'appel socket.recvfrom()

from socket import * 
from threading import Thread 
from sys import exit 

class TestThread(Thread): 
    def __init__(self,host="localhost",port=9999): 
     self.sock = socket(AF_INET,SOCK_DGRAM) 
     self.sock.bind((host,port)) 
     super(TestThread,self).__init__() 

    def run(self): 
     while True: 
      try: 
       recv_data,addr = self.sock.recvfrom(1024) 
      except (KeyboardInterrupt, SystemExit): 
       sys.exit() 

if __name__ == "__main__": 
    server_thread = TestThread() 
    server_thread.start() 
    while True: pass 

Le fil conducteur (celui qui exécute boucle infinie) sorties. Cependant le thread que je crée explicitement, reste suspendu dans recvfrom().

S'il vous plaît, aidez-moi à résoudre ce problème.

Répondre

4

Les interruptions du clavier sont toujours interceptées par le thread principal - jamais sur les threads "enfant". Pour éviter server_thread maintenir le processus en vie lorsque les principales sorties de fil, ne

server_thread.daemon = True 

avant d'appeler server_thread.start(). BTW, votre while True: pass dans le thread principal est inutilement des cycles de gravure de CPU. Vous devriez au moins le changer à quelque chose comme while True: time.sleep(1.0). Mais cela ne change pas la sémantique de votre code - il descend juste de 99% du CPU, à (je suppose) < 5% ;-).

+1

Yahoo !!! Ça marche. Merci beaucoup. > votre temps Vrai: le passage brûle inutilement les cycles du processeur. C'était juste pour illustrer le problème en gardant le code au minimum. – Dihlofos

1

Vous devez ouvrir un canal entre le thread principal et le thread réseau et sélectionner 'select' sur le socket et le tube. Lorsque vous souhaitez terminer le thread réseau, envoyez simplement un octet à travers le canal du thread principal et agissez en conséquence dans le thread réseau.

Juste mes 2 cents.

Questions connexes