2010-04-06 4 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.start()를 호출하기 전에 메인 스레드가 종료,

server_thread.daemon = True 

을 수행 할 때 살아 과정을 유지 server_thread을 방지하기 위해.

현재 주 스레드의 while True: pass은 불필요하게 CPU주기를 굽습니다. 적어도 while True: time.sleep(1.0)과 같은 것으로 변경해야합니다. 하지만 그것은 코드의 의미를 변경하지 않습니다. 99 %의 CPU에서 내려 받기 만하면됩니다. (내가 추측 할 때) < 5 % ;-).

+1

Yahoo !!! 그거야. 고마워. > 참 : 통과시 불필요하게 CPU 사이클을 굽습니다. 이것은 코드를 최소한으로 유지하는 문제를 설명하기위한 것입니다. – Dihlofos

1

파이프를 주 스레드에서 네트워크 스레드로 열고 소켓과 파이프 모두에서 '선택'해야합니다. 네트워크 스레드를 종료하려면 메인 스레드에서 파이프를 통해 바이트를 보내고 네트워크 스레드에서 적절하게 작동하십시오.

그냥 2 센트입니다.

관련 문제