2010-04-06 155 views
0

我無法終止掛起在socket.recvfrom()調用中的線程。例如,應該觸發KeyboardInterrupt異常的ctrl + c不能被捕獲。以下是我用於測試的腳本:python:無法終止掛在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 

主線程(執行無限循環的那個)退出。然而,我明確創建的線程仍然掛在recvfrom()中。

請幫我解決這個問題。

回答

4

鍵盤中斷總是在主線程中被捕獲 - 永遠不會在「子」線程中。爲了避免server_thread飼養過程活着的時候,主線程退出,做

server_thread.daemon = True 

你打電話之前server_thread.start()

順便說一句,你的while True: pass在主線程中是不必要的燃燒CPU週期。您至少應該將其更改爲while True: time.sleep(1.0)之類的內容。但是這並沒有改變你的代碼的語義 - 只是把它從99%左右的CPU降低到(我猜)< 5%;-)。

+1

Yahoo !!!這樣可行。非常感謝。 >你的同時True:pass是不必要的燃燒CPU週期。 這只是爲了說明保持代碼最小化的問題。 – Dihlofos 2010-04-06 15:03:30

1

您應該打開從主線程到網絡線程的管道,並在套接字和管道上選擇'select'。當您想要終止網絡線程時,只需從主線程通過管道發送一個字節,並在網絡線程中相應地執行操作。

只是我2美分。