我想有某种接收事件的服务器(即使用套接字),并且每个事件都有不同的ID(即dst端口号)。
是否有一种方法,从我看到特定ID的第一个数据包的那一刻起,我开始某种超时(即1ms),如果在此时间内没有收到具有相同ID的其他事件被触发,但如果收到了超时被重置为1ms。
我已经看到这样的事情可以通过使用signals
和SIGALARM
信号来完成。但是,我想为每个不同的ID保留多个"计时器"。
听起来像是select
的工作。当您使用套接字时,您有一个客户端的套接字描述符(假设每个客户端都有一个,但只要您有一个,它就可以工作)。因此,您要么等待数据包到达您的一个套接字,要么等待超时发生。这正是select
所做的。
因此,在接收消息时计算每个客户机的过期时间,然后在主循环中,简单地计算最快过期超时,并将其作为timeout
参数提供给select.select
(将所有套接字描述符作为rlist
参数)。然后,当新的数据包/消息到达或最旧的超时过期时,您将被唤醒。如果它是一个新数据包,你处理该数据包并将该提供商的超时重置为1ms;否则,您将在超时到期时执行任何操作。
然后计算下一个过期超时。冲洗。泡沫。重复。
像这样:
now = time.time()
timeout = min([(client.expiration - now) for client in clients_list])
rrdy, wrdy, xrdy = select.select([client.sock for client in clients_list], [], [], timeout)
if not rrdy:
# Timeout
now = time.time()
for client in clients_list:
if client.expiration < now:
process_timeout(client)
else:
# Process incoming messages
for rsock in rrdy:
process_message(rsock.recv(4096))
client.expiration = time.time() + .001
参见sched
内置模块,它有一个调度程序。
你可以构造一个新的scheduler实例,然后使用scheduler.enter
来调度一个延迟后被调用的函数;如果在限定时间内收到消息,则可以使用scheduler.cancel(event)
将其事件从队列中删除;您可以使用scheduler.run()
在另一个线程中运行调度程序,或者您可以在带有超时的选择多路复用线程中使用scheduler.run(blocking=False)
。