简体   繁体   English

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

[英]python: can't terminate a thread hung in socket.recvfrom() call

I cannot get a way to terminate a thread that is hung in a socket.recvfrom() call. 我无法终止挂在socket.recvfrom()调用中的线程。 For example, ctrl+c that should trigger KeyboardInterrupt exception can't be caught. 例如,无法捕获应触发KeyboardInterrupt异常的ctrl + c。 Here is a script I've used for testing: 这是我用于测试的脚本:

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

The main thread (the one that executes infinite loop) exits. 主线程(执行无限循环的线程)退出。 However the thread that I explicitly create, keeps hanging in recvfrom(). 但是,我显式创建的线程一直挂在recvfrom()中。

Please, help me resolve this. 请帮我解决这个问题。

Keyboard interrupts are always caught on the main thread -- never on "child" threads. 键盘中断始终捕获在主线程上,而不是“子”线程上。 To avoid server_thread keeping the process alive when the main thread exits, do 为了避免在主线程退出时server_thread使进程保持活动状态,请执行

server_thread.daemon = True

before you call server_thread.start() . 在调用server_thread.start()

BTW, your while True: pass in the main thread is needlessly burning CPU cycles. 顺便说一句,您while True: pass主线程会不必要地消耗CPU周期。 You should at least change it to something like while True: time.sleep(1.0) . 您至少应该将其更改为while True: time.sleep(1.0) But that doesn't change the semantics of your code -- just gets it down from 99% CPU or so, to (I'd guess) < 5%;-). 但这并不会改变代码的语义-只是将其代码从99%左右的CPU降低到(我猜是)<5%;-)。

You should open a pipe from the main thread to the network thread and 'select' on both the socket and the pipe. 您应该打开从主线程到网络线程的管道,并在套接字和管道上都进行“选择”。 When you want to terminate the network thread, just send a byte through the pipe from the main thread and act accordingly in the network thread. 当您要终止网络线程时,只需通过管道从主线程发送一个字节,然后在网络线程中采取相应措施即可。

Just my 2 cents. 只是我的2美分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM