【问题标题】:Use std::mutex for a thread pool managed by boost::asio对 boost::asio 管理的线程池使用 std::mutex
【发布时间】:2012-12-27 22:21:47
【问题描述】:

不知何故,this question 的后续行动。我只是想知道在boost::asio:io_service 处理的函数中使用std::mutex 是否可以?股线的使用有点不切实际。根据我在boost reference 中找到的内容,我会说没关系。既然它声明了

只会从当前正在调用 io_service::run() 的线程中调用异步完成处理程序。

所以 boost 创建的其他线程不应该干扰。我做对了吗?

【问题讨论】:

    标签: c++ multithreading boost c++11 boost-asio


    【解决方案1】:

    正如其他人所指出的,std::mutex 和其他锁定机制可以在处理程序中使用。但是,两者之间存在根本区别:

    • 处理程序中的外部锁定机制用于保护资源免受竞争条件的影响。
    • strand 用于消除处理程序之间的争用,从而消除处理程序之间的竞争条件。

    如果整个处理程序由于与其他处理程序的潜在竞争条件而同步,而不是线程池外部的线程,那么我想强调外部机制和boost::asio::strand 之间同步的细微差别之一.

    考虑以下场景:

    • 使用 Boost.Asio 实现 2 个线程的线程池。
    • 处理程序AB 将在同一个互斥体上同步。
    • 处理程序C 不需要同步。
    • 处理程序ABC 发布到io_service

    AB 被调用。由于外部同步,线程池现在已耗尽,因为两个线程都在使用。不幸的是,其中一个线程在资源上被阻塞,导致不需要同步的处理程序(例如C)坐在队列中。

    如果在这种情况下使用链进行同步,则不会发生这种饥饿实例。 strand 维护自己的处理程序队列,并保证其处理程序中只有一个处理程序在io_service 中,从而导致处理程序在放入io_service 之前被同步。在该场景中,如果AB 被发布到strand,那么strandA 发布到io_service。这将导致ACio_service 中,允许C 并发运行,而B 留在strand 的队列中等待A 完成。

    此外,还有一些用例可以同时使用这两种同步形式。例如,考虑与在线程池之外运行的线程共享资源的情况。线程池内部和外部的线程仍然需要互斥锁。但是,strand 可用于消除线程池内部线程之间的互斥锁争用。

    【讨论】:

    • 确实不错。就我而言,我想混合使用 strand 和 mutex,因为我有一些大型函数在某些时候需要共享资源。但我认为阻止整个函数运行的资源是一种矫枉过正的做法。我猜,将函数拆分成许多小的函数一个接一个地发布到 asio 会显着增加 asio 线程池的开销。
    【解决方案2】:

    完成处理程序内部的互斥锁可以阻止线程执行。在这种情况下,您需要比boost::thread::hardware_concurrency() 更多的io_service 线程来100% 加载CPU。它增加了线程切换开销。

    【讨论】:

      【解决方案3】:

      boost 只是从它的角度调用回调。这个回调与boost 无关,所以boost 不关心你在回调中做了什么。因此,锁定(使用您想要的任何锁定库)非常好。

      【讨论】:

        【解决方案4】:

        是的,在处理程序内部使用std::mutex 非常好。 strand 毕竟只是一个伪装成互斥体的队列。

        【讨论】:

        • 那么,使用 asio strands 有什么好处呢?
        猜你喜欢
        • 2012-08-26
        • 2011-12-18
        • 1970-01-01
        • 1970-01-01
        • 2011-09-03
        • 2017-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多