问题描述
我遇到的问题是很难找到已经解决的问题。
我正在运行一个新的python线程,该线程随后被套接字连接(python-socketio)阻塞,因为它无限期地等待数据。但是我需要在5分钟后关闭该线程。
我尝试设置一个计时器,该计时器将使用sys.exit()
关闭线程,但是我发现这正在关闭计时器线程本身。
这是到目前为止的代码:
class LiveMatches(commands.Cog):
def __init__(self,client):
self.client = client
def connect_to_scorebot(self,id):
Feed = MatchFeed(self.client)
Feed.main(id) # when this function is called,# it will block the newly created thread to receive the data with the socket
def create_thread(self,id):
# we create the thread and call launch_match that will connect to
# the scorebot
new_thread = threading.Thread(target=self.connect_to_scorebot,args=(id,))
# start the thread
new_thread.start()
解决方法
几个选项:
- 您可以在线程中使用的套接字上设置超时,以便一段时间后从阻塞状态返回。
- 使用
select.select()
和超时来轮询套接字以获取数据,并定期检查线程是否应该退出。
第1个示例:
import threading
import socket
import select
# A server that echos only the first data received from a client
def server():
s = socket.socket()
s.bind(('',5000))
s.listen()
print('server: running')
while True:
c,a = s.accept()
print('server: client connected')
with c: # closes client socket when with block exits
echoed = False
while True:
data = c.recv(1024)
if not data: break
if not echoed:
print('server: responding',data)
c.sendall(data)
echoed = True
print('server: client disconnected')
def client():
s = socket.socket()
s.connect(('localhost',5000))
with s: # closes client socket when with block exits
try:
s.settimeout(5) # 5-second timeout if no data received.
print('client: send one')
s.sendall(b'one')
print('client: got',s.recv(1024))
print('client: send two')
s.sendall(b'two')
print('client: got',s.recv(1024)) # this will timeout
except socket.timeout:
print('client: timed out')
# Start server thread.
# As a daemon,it will exit if main thread and client thread both exit.
threading.Thread(target=server,daemon=True).start()
t = threading.Thread(target=client)
t.start()
t.join() # wait for client thread to exit.
t = threading.Thread(target=client)
t.start()
t.join() # wait for client thread to exit.
输出:
server: running
client: send one
server: client connected
server: responding b'one'
client: got b'one'
client: send two
client: timed out
server: client disconnected
client: send one
server: client connected
server: responding b'one'
client: got b'one'
client: send two
client: timed out
Note服务器没有打印第二个客户端已断开连接。由于它是守护程序线程,因此在主线程和客户端线程都退出时终止,并且没有时间识别超时后客户端已断开连接。如果您想要更干净的退出行为,请不要使用守护线程。