2

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

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

我对大量对象不起作用的方法如下:

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

操作系统:Linux。

我想在 c++ 中实现这个,我从来没有实现过这个,所以我需要你的帮助和指导才能继续前进。任何在线教程,参考都会有很大帮助。提前致谢。

4

3 回答 3

2

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

该代码适用于 Windows,因此您必须根据我的预期对其进行一些调整。

该代码设计用于处理数千个网络连接,其中每个连接都可能有一个或多个与之关联的计时器。它已被具有超过 10,000 个连接的系统使用,并且运行良好且高效。

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

系列从这里开始。

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

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

于 2013-08-11T20:33:17.623 回答
0

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

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

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

这种 A/B/C 场景的替代解决方案是有一个“阅读器助手”线程,它无限期地等待网络数据(案例 B),而主线程对 A 和 C 使用 pthread_cond_timedwait()。助手线程将发出信号数据通过 pthread_cond_signal 到达,因此基本上将 case B 转换为 case A。顺便说一句:如果主线程在任何时候选择中止连接,它可能只是强制 close() 网络连接,这也会终止 read()等待帮助线程的调用。

于 2013-08-11T18:14:39.343 回答
0

您需要使用事件循环,例如boost::asio timer tutorialslibevent events

于 2013-08-11T17:57:49.450 回答