[英]Use std::mutex for a thread pool managed by boost::asio
Somehow a followup of this question . 不知怎的, 这个问题的后续行动。 I am only wondering if it is ok to use a std::mutex
in functions handeled by a boost::asio:io_service
? 我只是想知道在boost::asio:io_service
函数中使用std::mutex
可行? Usage of strands is somwhat unpractical. 使用股线是不切实际的。 From what I found in the boost reference I would say it is ok. 从我在boost参考中找到的我会说它没问题。 Since it states that 既然它说明了这一点
Asynchronous completion handlers will only be called from threads that are currently calling io_service::run(). 只能从当前调用io_service :: run()的线程调用异步完成处理程序。
So other threads created by boost should not interfere. 所以boost创建的其他线程不应该干扰。 Did I get it right? 我做对了吗?
As others have noted, std::mutex
and other locking mechanics, can be be used within handlers. 正如其他人所说, std::mutex
和其他锁定机制,可以在处理程序中使用。 However, there is a fundamental difference between the two: 但是,两者之间存在根本区别:
strand
is used to remove contention between handlers, resulting in the removal of race conditions between handlers. 一条strand
用于消除处理程序之间的争用,从而消除处理程序之间的竞争条件。 If the entire handler is being synchronized as a result of potential race conditions with other handlers, and not threads external to the threadpool, then I would like to accentuate one of the subtle differences in synchronization between an external mechanism and boost::asio::strand
. 如果整个处理程序由于与其他处理程序的潜在竞争条件而被同步,而不是线程池外部的线程,那么我想强调外部机制和boost::asio::strand
之间的同步中的一个细微差别。 boost::asio::strand
。
Consider the following scenario: 请考虑以下情形:
A
and B
will be synchronized on the same mutex. 处理程序A
和B
将在同一个互斥锁上同步。 C
requires no synchronization. 处理程序C
不需要同步。 A
, B
, and C
are posted into the io_service
. 处理程序A
, B
和C
将发布到io_service
。 A
and B
are invoked. 调用A
和B
The threadpool is now exhausted due to external synchronization, as both threads are being used. 由于外部同步,线程池现在已耗尽,因为正在使用两个线程。 Unfortunately, one of the threads is blocked on a resource, causing handlers that require no synchronization, such as C
, to sit in the queue. 不幸的是,其中一个线程在资源上被阻塞,导致不需要同步的处理程序(例如C
位于队列中。
If a strand is used for synchronization in this scenario, then this instance of starvation would not have occurred. 如果在此方案中使用strand进行同步,则不会发生此饥饿实例。 A strand
maintains its own handler queue, and guarantees that only one of its handlers is in the io_service
, resulting in handlers being synchronized before being placed into the io_service
. 一个strand
维护自己的处理程序队列,并保证只有一个处理程序在io_service
,导致处理程序在被放入io_service
之前被同步。 In the scenario, if A
and B
are posted into the strand
, then the strand
will post A
into the io_service
. 在该场景中,如果A
和B
被发布到strand
,则strand
将A
发布到io_service
。 This would result in A
and C
being in the io_service
, allowing C
to run concurrently while B
remains in the strand
's queue waiting for A
to complete. 这将导致A
和C
位于io_service
,允许C
同时运行,而B
保留在strand
的队列中,等待A
完成。
Also, there are use cases where both of these forms of synchronization can be used together. 此外,还有一些用例可以同时使用这两种形式的同步。 For example, consider the case where resources are shared with a thread running outside of the threadpool. 例如,考虑资源与在线程池外部运行的线程共享的情况。 A mutex would still be required by threads internal and external to the threadpool. 线程池内部和外部的线程仍然需要互斥锁。 However, a strand
could be used to remove the contention for the mutex between threads internal to the threadpool. 但是,可以使用strand
来消除线程池内部线程之间的互斥锁争用。
Yes, using a std::mutex
inside of a handler is perfectly fine. 是的,在处理程序中使用std::mutex
非常好。 A strand
is just a queue with a mutex in disguise after all. 毕竟,一个strand
只是一个伪装成互斥的队列。
boost
is simply calling a callback from its perspective. boost
只是从它的角度调用回调。 This callback has no relation to boost
, so boost
doesn't care what you do in the callback. 这个回调与boost
无关,所以boost
不关心你在回调中做了什么。 So taking a lock (using any locking library you desire), is perfectly fine. 因此,锁定(使用您想要的任何锁定库)是完全没问题的。
Mutex inside completion handler can block thread execution. Mutex内部完成处理程序可以阻止线程执行。 In that case you need more io_service
threads than boost::thread::hardware_concurrency()
to load CPU for 100%. 在这种情况下,您需要比boost::thread::hardware_concurrency()
更多的io_service
线程来加载100%的CPU。 It increases thread switching overhead. 它增加了线程切换开销。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.