I'm having an issue that is really difficult to find an already made solution for it.
I'm running a new python thread that is then blocked by a socket connection (python-socketio) because it is waiting indefinitely for data. But I need to close this thread after 5 minutes. I've tried to setup a timer that would close the thread with sys.exit()
but I found that this was closing the timer thread itself.
Here is the code so far:
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()
A couple of options:
select.select()
with a timeout to poll a socket for data, periodically checking if the thread should exit.Example of #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.
Output:
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 server didn't print that the second client disconnected. Since it is a daemon thread, it was terminated when the main thread and client thread both exited, and didn't have time to recognize the client disconnected after timeout. If you want cleaner exit behavior, don't use daemon threads.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.