以某种方式跟进this question。我只是想知道在std::mutex
处理的函数中使用boost::asio:io_service
是否可以?使用股线是不切实际的。从我在boost reference中找到的内容我会说它没问题。因为它说明了
只能从当前调用io_service :: run()的线程调用异步完成处理程序。
因此,boost创建的其他线程不应该干扰。我做对了吗?
答案 0 :(得分:11)
正如其他人所说,std::mutex
和其他锁定机制可以在处理程序中使用。但是,两者之间存在根本区别:
strand
用于消除处理程序之间的争用,从而消除处理程序之间的竞争条件。如果整个处理程序由于与其他处理程序的潜在竞争条件而被同步,而不是线程池外部的线程,那么我想强调外部机制和{{1}之间的同步中的一个细微差别。 }}
考虑以下情况:
boost::asio::strand
和A
将在同一个互斥锁上同步。B
不需要同步。C
,A
和B
已发布到C
。 io_service
和A
被调用。由于外部同步,线程池现在已耗尽,因为正在使用两个线程。不幸的是,其中一个线程在资源上被阻塞,导致不需要同步的处理程序(例如B
)位于队列中。
如果在此方案中使用strand进行同步,则不会发生此饥饿实例。 C
维护自己的处理程序队列,并保证只有一个处理程序在strand
中,从而导致处理程序在被放入io_service
之前被同步。在该方案中,如果io_service
和A
发布到B
,则strand
会将strand
发布到A
。这会导致io_service
和A
位于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。它增加了线程切换开销。