我想要某种类型的服务器接收事件(即使用套接字),并且每个事件都有不同的ID(即dst端口号)。Python:设置多个连续超时
有没有一种方法,从我看到特定ID的第一个数据包的那一刻起,我开始某种超时(即1ms),并且如果在那段时间内没有收到其他具有相同ID的事件,被触发,但如果收到某些事件,超时重置为1ms。
我已经看到类似的东西可以通过使用signals
和SIGALARM
信号来完成。但是,我想为每个不同的ID保留多个“计时器”。
我想要某种类型的服务器接收事件(即使用套接字),并且每个事件都有不同的ID(即dst端口号)。Python:设置多个连续超时
有没有一种方法,从我看到特定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
我认为这应该有效,但如果两者之间的操作太多,我可能会遇到问题,不是吗?由于超时很小。 – edgarstack
查看sched
内置模块,它有一个调度程序。
您可以构造一个新的调度器实例,然后使用scheduler.enter
来调度在延迟后调用的函数;如果您在时间限制内收到消息,则可以使用scheduler.cancel(event)
从队列中删除其事件;您可以使用scheduler.run()
在另一个线程中运行调度程序,也可以在具有超时的选择多路复用线程中使用scheduler.run(blocking=False)
。
您可以在运行时将事件输入到调度程序中吗?因为每次收到活动时都必须取消并重新输入。如果我在10毫秒内收到同一事件的1000个事件(这意味着我必须每次取消并输入一个新的计时器),这样做的表现会不错吗?从理论上讲,所有同类型的事件都会聚集在一起,但我不知道何时应该考虑所有这些事件,所以我必须监视我什么时候没有收到它们。 – edgarstack
的可能的复制[Python中:运行多个同时定时器(http://stackoverflow.com/questions/26446110/python-running-multiple-timers-simultaneously) –
什么我想要的是不同的,在答案中他们只给出了一个例子,说明如何在X时间之后使用'threading.Timer'执行一个函数。我想要监听一些事件,直到一个事件不会在1ms后出现,但仍然在监听其他正在到达并未“过期”的事件 – edgarstack