使用std :: mutex作为boost :: asio管理的线程池

时间:2013-01-14 01:30:36

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

以某种方式跟进this question。我只是想知道在std::mutex处理的函数中使用boost::asio:io_service是否可以?使用股线是不切实际的。从我在boost reference中找到的内容我会说它没问题。因为它说明了

  

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

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

4 个答案:

答案 0 :(得分:11)

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

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

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

考虑以下情况:

  • 使用Boost.Asio。
  • 实现2个线程的线程池
  • 处理程序boost::asio::strandA将在同一个互斥锁上同步。
  • 处理程序B不需要同步。
  • 处理程序CAB已发布到C

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

如果在此方案中使用strand进行同步,则不会发生此饥饿实例。 C维护自己的处理程序队列,并保证只有一个处理程序在strand中,从而导致处理程序在被放入io_service之前被同步。在该方案中,如果io_serviceA发布到B,则strand会将strand发布到A。这会导致io_serviceA位于C,允许io_service同时运行,C保留在B的队列中等待strand完成。

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

答案 1 :(得分:8)

是的,在处理程序内部使用std::mutex完全没问题。毕竟,strand只是伪装成互斥的队列。

答案 2 :(得分:2)

boost只是从它的角度调用回调。此回调与boost无关,因此boost不关心您在回调中执行的操作。因此,锁定(使用您想要的任何锁定库)非常好。

答案 3 :(得分:0)

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