如何在c++中为每个对象实现定时器

How to implement timer for each object in c++?

本文关键字:对象 实现 定时器 c++      更新时间:2023-10-16

我需要实现以下场景,请帮助我:

  1. 将维护一个队列,其中将包含一些对象
  2. 当一个对象插入队列时,将为该对象启动一个计时器
  3. 每当该对象上发生事件时,都会发送一个信号(该事件可能像超时、某些错误等)
  4. 将捕获此对象发生的事件,并接收对象Id。需要对象Id来区分队列中存在的对象并采取适当的操作

我的方法不适用于大量对象,如下所示:

  1. 为每个对象创建一个线程,该线程将向thread_function1(void *object_id);传递对象Id,并使用sleep()作为该对象的计时器
  2. 现在,对于其他对象,我必须通过创建new thread_function2(void *object_id);来做同样的事情上面的方法不会起作用,因为我希望它是动态的

操作系统:Linux。

我想在c++中实现这一点,我从未实现过,所以我需要您的帮助和指导才能继续前进。任何在线教程,参考资料都会有很大帮助。提前谢谢。

早在2004年,我就开始写一系列名为"实用测试"的博客文章,展示了如何测试C++定时器实现。该系列由许多版本的功能齐全的轻量级定时器队列组成,该队列使用单个线程为定时器提供服务(当然,一旦定时器事件触发,您可以将其传递给线程池,但队列本身只需要一个线程即可工作)。

代码是针对Windows的,所以我想你必须对它进行一些调整。

该代码设计用于数千个网络连接,其中每个连接都可能有一个或多个与之相关的计时器。它已被拥有10000多个连接的系统使用,运行良好且高效。

在第23集中,我添加了一个使用定时器轮而不是定时器队列的替代实现,并讨论了获得新数据结构带来的性能提升所需的权衡。

这个系列从这里开始。

如果你只是想要最新的工作代码,那么可以从第31集下载,点击这里。

该代码具有良好的单元测试覆盖率(我希望,毕竟这是博客文章的重点),测试可以随代码一起下载。

您需要使用事件循环,例如boost::asio计时器教程或libevent事件。

简单的答案是:不要使用sleep()。这是一个非常尴尬的旧界面,你不应该再在任何代码中使用它了。

特别是sleep()并不是最不具有线程意识的。相反,使用pthread库中的函数来满足您的时间需求。例如,您可以使用pthread_cond_timedwait()来限制线程等待某个事件的时间量。

不幸的是,创建pthread库的人忘记了创建与pthread兼容的标准系统调用版本,如read()或write()。因此,编程一个线程,等待以下任何一个:
A) 另一个线程表示某个状态
B) 通过网络连接接收数据
C) 超时
还是一团糟。一种解决方案是使用select()和/或poll()来等待数据(情况B)或超时(情况C),并使用管道/fifo返回自己以从另一个thead发送信号(情况a)。为此,将管道的读取端添加到select()集合中,如果需要发出条件信号,则让另一个线程向其写入一个字节。

这个A/B/C场景的另一种解决方案是有一个"读取器助手"线程,它无限期地等待网络数据(情况B),而主线程对A和C使用pthread_cond_timedwait()。助手线程将通过pthread-cond_signal发出数据到达的信号,从而基本上将情况B转换为情况A。顺便说一句:如果主线程在任何时候选择中止连接,它可能只是强制关闭()网络连接,这也将终止等待助手线程的read()调用。