gpt4 book ai didi

multithreading - boost ASIO IO_SERVICE 实现?

转载 作者:行者123 更新时间:2023-12-04 08:36:56 25 4
gpt4 key购买 nike

我正在编写一个异步日志记录框架,其中有多个线程转储数据。我开始玩 Boost asio 因为它提供了一些简单的方法来强制执行序列化和排序。由于我是初学者,我从线程安全(使用 boost::mutexboost:condition_variable )循环 bounded_buffer (实际上是向量)开始我的设计。

我写了一个简单的小基准来衡量性能。基准测试只是一个单线程记录一百万条消息(将其插入缓冲区),而我的工作线程只会从队列中获取消息以记录到文件/控制台/记录器列表。
(P.S. mutex 和 C.V 的使用是正确的,并且指向消息的指针正在移动,所以从这个角度来看,一切都很好/高效)。

当我将我的实现改为使用 boost::asio::io_service 时并且有一个线程执行 run()性能确实 boost 了(实际上,它在增加记录的消息数量而不是降低我最初的简单模型中的性能时可以很好地扩展)

以下是我想澄清的几个问题。

  • 为什么要 boost 性能? (我认为 boost::asio::io_service 内部实现具有用于处理程序的线程安全队列,是什么使它比我自己最初的简单线程安全队列设计更有效)。请注意,我的设计经过了很好的审查并且没有任何错误(框架代码基于经过验证的示例),有人可以更详细地了解如何io_service 的内部细节吗?实现这一点。
  • 第二个有趣的观察是,在增加线程时,我的初始实现性能有所 boost ,但以丢失序列化/排序为代价,但是使用 boost::asio 性能下降(非常轻微)(我认为这是因为我的处理程序正在做非常简单的任务并且上下文切换开销正在下降,我将尝试放置更复杂的任务并稍后发布我的观察)。
  • 我真的很想知道 boost::asio仅用于 i/o 和网络操作,或者我使用它通过线程池执行并发任务(并行)是一种很好的设计方法。是 io_service object 只是打算用于 i/o 对象(如文档中所写),但我发现它是一种非常有趣的方式,可以帮助我以序列化方式解决并发任务(不仅仅是 i/o 或网络相关)(有时强制使用排序)股)。我是 boost 的新手,真的很好奇为什么基本模型的性能/规模不如我使用 boost asio 时那么好。

  • 结果:(在两者中我只有 1 个工作线程)
  • 1000 个任务:两种情况下为 10 微秒/任务
  • 10000 个任务:80 微秒(有界缓冲区),10 微秒在 boost asio
  • 100000 个任务:250 微秒(边界缓冲区),10 微秒在 boost asio

  • 了解 boost 如何解决 io_service 中的线程安全问题会很有趣。处理程序的线程安全队列(我一直认为在某种程度的实现中,他们也必须使用锁和 c.v )。

    最佳答案

    恐怕我对(1)帮不上忙,但关于其他两个问题:

    (2)我发现boost::asio里面有一些开销非确定性的架构,即数据进入(或发送到 IO 服务对象)之间的延迟可以从几乎即时响应到数百毫秒的数量级变化。我试图将其量化为我试图解决的另一个关于记录和时间戳 RS232 数据的问题的一部分,但没有得到任何确凿的结果或稳定延迟的方法。发现上下文切换组件存在类似问题,我一点也不会感到惊讶。

    (3) 至于使用boost::asio对于异步 I/O 以外的任务,它现在是大多数异步操作的标准工具。我用 boost::asio定时器一直用于异步进程,并为其他任务生成超时。将多个工作线程添加到池中的能力意味着您也可以为其他异步高负载任务很好地扩展解决方案。我去年写的最简单和最喜欢的类是一个很小的工作线程类,用于 boost::asio IO 服务(如有错别字,请见谅,这是内存中的转录而不是剪切和粘贴):

    class AsioWorker
    {
    public:
    AsioWorker(boost::asio::io_service * service):
    m_ioService(service), m_terminate(false), m_serviceThread(NULL)
    {
    m_serviceThread = new boost::thread( boost::bind( &AsioWorker::Run, this ) )
    }
    void Run( void )
    {
    while(!m_terminate)
    m_ioService->poll_one();
    mySleep(5); // My own macro for cross-platform millisecond sleep
    }
    ~AsioWorker( void )
    {
    m_terminate = true;
    m_serviceThread->join();
    }
    private:
    bool m_terminate;
    boost::asio::io_service *m_ioService;
    boost::thread *m_serviceThread;
    }

    这门课是个很棒的小玩具,只需添加 new根据需要,和 delete一些当你完成它们时。贴一个 std::vector<AsioWorker*> m_workerPool进入使用 boost::asio 的设备类你可以进一步包装线程池管理的东西。我一直很想根据时间来编写一个智能池自动管理器来适本地增加线程池,但我还没有一个项目需要它。

    为了满足您对线程安全的好奇心,可以深入了解 boost 的本质,以准确了解它们是如何做的。就我个人而言,我总是从表面上看大部分 boost 功能,并根据过去的经验假设它在引擎盖下已经得到了很好的优化。

    关于multithreading - boost ASIO IO_SERVICE 实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9780817/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com