python:无法终止在socket.recvfrom()调用中挂起的线程

0 投票
2 回答
2377 浏览
提问于 2025-04-15 21:17

我无法找到一种方法来结束一个在socket.recvfrom()调用中卡住的线程。例如,按下ctrl+c本来应该触发一个叫做KeyboardInterrupt的异常,但我捕捉不到。下面是我用来测试的脚本:

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()里。

请帮我解决这个问题。

2 个回答

1

你应该在主线程和网络线程之间建立一个管道,然后在套接字和管道上进行“选择”。当你想要结束网络线程时,只需从主线程通过管道发送一个字节,然后在网络线程中做出相应的处理。

这只是我个人的一点建议。

4

键盘中断总是在主线程中被捕获,而不会在“子”线程中被捕获。为了避免当主线程退出时,server_thread 让进程继续运行,你需要在调用 server_thread.start() 之前做一些设置。

server_thread.daemon = True

顺便提一下,你在主线程中的 while True: pass 代码会无谓地消耗 CPU 资源。你至少应该把它改成 while True: time.sleep(1.0) 这样。虽然这样做并不会改变你代码的逻辑,但可以把 CPU 的使用率从大约 99% 降到我猜的不到 5%;-)

撰写回答