【发布时间】:2012-04-04 13:36:15
【问题描述】:
我正在编写一个异步日志框架,其中有多个线程转储数据。我开始使用 Boost asio,因为它提供了一些简单的方法来强制执行序列化和排序。由于我是初学者,因此我从线程安全(使用 boost::mutex 和 boost:condition_variable)循环 bounded_buffer(实际上是向量)开始我的设计。
我写了一个简单的小基准来衡量性能。基准测试只是一个记录一百万条消息的单个线程(将其推入缓冲区),我的工作线程只会从队列中获取消息以记录到文件/控制台/记录器列表。 (P.S. mutex 和 C.V 的使用是正确的,并且指向消息的指针正在移动,所以从这个角度来看,一切都很好/高效)。
当我将实现更改为使用 boost::asio::io_service 并让单个线程执行 run() 时,性能确实得到了提升(实际上,它在增加记录的消息数量而不是在我最初的性能下降方面做得很好简单模型)
这里有几个我想澄清的问题。
为什么要提高性能? (我认为
boost::asio::io_service内部实现有处理程序的线程安全队列,是什么让它比我自己最初的简单线程安全队列设计更有效)。请注意,我的设计经过了很好的审查并且没有任何错误(骨架代码基于经过验证的示例),有人可以更详细地了解io_service如何实现这一点的内部细节。第二个有趣的观察结果是,在增加线程时,我的初始实现性能有所提高,但以丢失序列化/排序为代价,但使用 boost::asio 时性能下降(非常轻微)(我认为这是因为我的处理程序正在执行非常简单的任务并且上下文切换开销正在下降,我将尝试放置更复杂的任务并稍后发布我的观察结果。
我真的很想知道
boost::asio是否仅用于 i/o 和网络操作,或者我使用它通过线程池执行并发任务(并行)是一种很好的设计方法。io_service对象是否只是用于 i/o 对象(如文档中所写),但我发现它是一种非常有趣的方式,可以帮助我以序列化方式解决并发任务(不仅仅是 i/o 或网络相关)(有时使用链强制排序)。我是 boost 新手,真的很好奇为什么基本模型的性能/规模不如我使用 boost asio 时那么好。
结果:(在这两个中我只有 1 个工作线程)
- 1000 个任务:两种情况下每个任务都需要 10 微秒
- 10000 个任务:80 微秒(有界缓冲区),在 boost asio 中为 10 微秒
- 100000 任务:250 微秒(边界缓冲区),10 微秒 in boost asio
了解 boost 如何解决处理程序的 io_service 线程安全队列中的线程安全问题会很有趣(我一直认为在某种实现级别上,他们也必须使用锁和 c.v )。
【问题讨论】:
-
我使用
boost::asio来管理其他类型的异步任务(不仅仅是网络 IO)并取得了很好的成功。 -
我知道这是一个老问题,但可能是(在 Windows 上),ASIO 使用 IO 完成端口,这可能会导致整体系统调用减少。
标签: multithreading boost thread-safety boost-asio threadpool