如何中断在 Python 中的不同线程中运行的 socket.accept()?

Bin*_*bik 1 python sockets multithreading

我想编写一个接受 tcp 连接的服务器,但我不想在调用时阻塞主线程socket.accept(),所以我想将网络放在不同的线程中。我已经看到没有办法在 Python 中中断线程,现在我想知道如何停止socket.accept()正确调用。

我想要的解决方案类似于 Java,例如:

class TcpServer:
    def waitForConnection():
        try:
            conn, addr = socket.accept()
        except ThreadInterrupt:
            # Close server ...
Run Code Online (Sandbox Code Playgroud)

不幸的是,这个“ThreadInterrupt”不存在。那么,我怎样才能实现这种行为呢?预先感谢每个提示。

Jir*_*iri 5

您可以settimeout通过某个变量使用并向线程发出信号(CONDITION在我的示例中):

CONDITION = False
s.settimeout(1.0)
while True:
    try:
        if CONDITION: break
        conn, addr = s.accept()
        break

    except socket.timeout as e:
        pass
Run Code Online (Sandbox Code Playgroud)

在另一个线程中,您必须将 设为CONDITIONTrue 并且可以在块CONDITION后进行测试while


mgu*_*arr 5

您可以将套接字设置为非阻塞操作,并等待select它准备好accept(当它第一次变得可读时)。附加值是您可以侦听另一个文件描述符,例如管道,这样您就拥有与线程的特权通信通道,并且您可以随时退出线程:

import select
import socket
import os

class TcpServer:
    def __init__(self, ...):
        self.r_channel, self.w_channel = os.pipe() 
        self.socket = ...
    def waitForConnection(self):
        rfds, _, _ = select.select([self.socket.fileno(), self.r_channel],[],[])
        if self.r_channel in rfds:
            # close server
            ...
        self.socket.accept() # this won't block

# if you want to interrupt waitForConnection, from main thread:
os.write(tcp_server_object.w_channel, '!') # write something, just to wake up the select call
Run Code Online (Sandbox Code Playgroud)