Python:如何停止正在等待.recv()的线程

问题描述 投票:2回答:2

我正在运行此线程:

def run(self):
    while 1:
        msg = self.connection.recv(1024).decode()

我希望像这样关闭Tkinter窗口时可以结束该线程:

self.window.protocol('WM_DELETE_WINDOW', self.closeThreads)

def closeThreads(self):
    self.game.destroy()
    #End the thread

不能使用thread._close(),因为它已被弃用,而Python 3.4不允许使用。

python multithreading
2个回答
2
投票

两种解决方案:

1)不要停止线程,仅当进程以sys.exit()退出时才允许线程死亡>

2)使用“立即死亡”标志启动线程。 Event类专门用于从另一个线程发出信号。

下面的示例启动一个线程,该线程连接到服务器。任何数据都会被处理,并且如果父对象发出信号退出线程,它将处理。作为附加的安全功能,我们有一个警报信号

可以杀死所有东西,以防万一某些东西失控。

来源
import signal, socket, threading

class MyThread(threading.Thread):
    def __init__(self, conn, event):
        super(MyThread,self).__init__()
        self.conn = conn
        self.event = event

    def handle_data(self):
        "process data if any"
        try:
            data = self.conn.recv(4096)
            if data:
                print 'data:',data,len(data)
        except socket.timeout:
            print '(timeout)'

    def run(self):
        self.conn.settimeout(1.0)
        # exit on signal from caller
        while not self.event.is_set():
            # handle any data; continue loop after 1 second
            self.handle_data()
        print 'got event; returning to caller'


sock = socket.create_connection( ('example.com', 80) )
event = threading.Event()

# connect to server and start connection handler
th = MyThread(conn=sock, event=event)

# watchdog: kill everything in 3 seconds
signal.alarm(3)

# after 2 seconds, tell data thread to exit 
threading.Timer(2.0, event.set).start()

# start data thread and wait for it
th.start()
th.join()

输出
(timeout)
(timeout)
got event; returning to caller


1
投票

我为这个问题看到的唯一真正令人满意的解决方案是不允许您的线程在recv()内部阻塞。而是将套接字设置为非阻塞,并将线程阻塞在select()内。在select()内部进行阻塞的好处是,您可以告诉select()在几个套接字中的任何一个变得可读取时返回,这将使我们进入下一部分:作为设置线程的一部分,请创建第二个线程。套接字(例如socketpair提供的本地连接的TCP套接字,或侦听端口上来自本地主机的数据包的UDP套接字)。当您的主线程希望您的网络线程消失时,您的主线程应该向该套接字发送一个字节(或者在TCP情况下,主线程可能只是关闭其套接字对的末端)。这将导致select()返回该套接字上的就绪读取,并且当您的网络线程意识到该套接字被标记为就绪读取时,它应立即退出以做出响应。

© www.soinside.com 2019 - 2024. All rights reserved.