我需要使用生存时间参数维护多个对象,并在超时时触发某种事件。
实现这个作为一个计时器,只是等待一个具有最小TTL的对象,然后将其从队列中弹出它并不是非常有效,因为我需要能够偶尔添加/删除此队列中的对象(和他们可能有任何超时的价值),可能在他们超时之前。例如,如果我认为最短的TTL对象是10秒并且阻止超时线程持续10秒,那么就会发生丑陋的事情,但在此期间,一个有3秒生存的对象被添加到队列中。
天真的做事方式
while (true) {
update()
}
void update() {
// get delta since last call to update()
// subtract delta from each object and time out if ttl < 0
}
非常慢,因为为了更新微秒级分辨率的ttl,有很多内存被改组。
有没有一种好方法可以在不为每个对象创建单独的线程的情况下执行此操作?
我可以访问C ++ 11 std lib但没有boost或任何外部库。
答案 0 :(得分:0)
一个 easy 但有点糟糕的选择是轮询队列的更新 - 比如说每秒或十分之一秒。很多时候,你的操作系统可能没有时间来完成一些有成效的工作;很少,你的计时能力变得非常粗糙。您可以使用std::this_thread::sleep_for(std::chrono::milliseconds(n))
进行轮询间延迟,也可以使用例如select
如果您正在进行其他I / O操作。您可以通过互斥锁对队列进行任何访问,并使用std::map<std::chrono::time_point, Task>
来保持Tasks
按TTL排序,因此每次轮询周期到期时,您只需从.begin()
向{i}迭代.end()
,如果time_point
尚未过去,则提前退出。
...没有为每个对象创建单独的线程?
如果需要,上面的操作可以是单个后台线程。
另一种选择:非标准OS提供的异步通知机制,例如信号提升警报......例如alarm
,但是你的信号通常只允许进行相当有限数量的操作,正常的建议是设置一个标志,这样被打断的线程可以知道它的工作是什么 - &#&## 39;无论如何都必须检查队列是否过期Tasks
,但优点是信号本身可以强制某些阻塞操作提前终止(例如没有SA_RESTART
标志到{{1} }),错误代码指示中断的原因。几十年前,我在某些操作系统上遇到了一些阻塞操作,这些操作系统对中断的例程可能使用的I / O缓冲区状态提供了有限的保证,使得无法建立强大的I / O恢复 - 检查您的操作系统文档