[英]Use std::mutex for a thread pool managed by boost::asio
正如其他人所说, std::mutex
和其他锁定机制,可以在处理程序中使用。 但是,两者之间存在根本区别:
strand
用于消除处理程序之间的争用,从而消除处理程序之间的竞争条件。 如果整个处理程序由于与其他处理程序的潜在竞争条件而被同步,而不是线程池外部的线程,那么我想强调外部机制和boost::asio::strand
之间的同步中的一个细微差别。 boost::asio::strand
。
请考虑以下情形:
A
和B
将在同一个互斥锁上同步。 C
不需要同步。 A
, B
和C
将发布到io_service
。 调用A
和B
由于外部同步,线程池现在已耗尽,因为正在使用两个线程。 不幸的是,其中一个线程在资源上被阻塞,导致不需要同步的处理程序(例如C
位于队列中。
如果在此方案中使用strand进行同步,则不会发生此饥饿实例。 一个strand
维护自己的处理程序队列,并保证只有一个处理程序在io_service
,导致处理程序在被放入io_service
之前被同步。 在该场景中,如果A
和B
被发布到strand
,则strand
将A
发布到io_service
。 这将导致A
和C
位于io_service
,允许C
同时运行,而B
保留在strand
的队列中,等待A
完成。
此外,还有一些用例可以同时使用这两种形式的同步。 例如,考虑资源与在线程池外部运行的线程共享的情况。 线程池内部和外部的线程仍然需要互斥锁。 但是,可以使用strand
来消除线程池内部线程之间的互斥锁争用。
是的,在处理程序中使用std::mutex
非常好。 毕竟,一个strand
只是一个伪装成互斥的队列。
boost
只是从它的角度调用回调。 这个回调与boost
无关,所以boost
不关心你在回调中做了什么。 因此,锁定(使用您想要的任何锁定库)是完全没问题的。
Mutex内部完成处理程序可以阻止线程执行。 在这种情况下,您需要比boost::thread::hardware_concurrency()
更多的io_service
线程来加载100%的CPU。 它增加了线程切换开销。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.