void strand_service::do_post(implementation_type& impl,
operation* op, bool is_continuation)
{
impl->mutex_.lock();
if (impl->locked_)
{
// Some other handler already holds the strand lock. Enqueue for later.
impl->waiting_queue_.push(op);
impl->mutex_.unlock();
}
else
{
// The handler is acquiring the strand lock and so is responsible for
// scheduling the strand.
impl->locked_ = true;
impl->mutex_.unlock();
impl->ready_queue_.push(op);
io_service_.post_immediate_completion(impl, is_continuation);
}
}
</pre><pre code_snippet_id="574372" snippet_file_name="blog_20150107_3_5213123" name="code" class="cpp">如上。
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">
</span>
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">
</span>
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">
</span>
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">strand 最多193个。 也不需要太担心strand过多会影响效率或者浪费资源的问题。</span>
impl就是strand实现类, 内部还是有锁。
只不过锁的范围内没做什么事情, 检查状态 push/pop之类的; 尽量减少持有锁的时间, 通过这种方式来增强并发。
因为线程获取锁之后马上就释放了。 其他线程尝试获取锁时的争用情况大大减少了。 基本不会争用,更不可能会卡住。
但是直接用mutex, 就可能出现被卡住的情况。
private:
// Helper function to dispatch a handler. Returns true if the handler should
// be dispatched immediately.
BOOST_ASIO_DECL bool do_dispatch(implementation_type& impl, operation* op);
// Helper fiunction to post a handler.
BOOST_ASIO_DECL void do_post(implementation_type& impl,
operation* op, bool is_continuation);
BOOST_ASIO_DECL static void do_complete(io_service_impl* owner,
operation* base, const boost::system::error_code& ec,
std::size_t bytes_transferred);
// The io_service implementation used to post completions.
io_service_impl& io_service_;
// Mutex to protect access to the array of implementations.
boost::asio::detail::mutex mutex_;
// Number of implementations shared between all strand objects.
#if defined(BOOST_ASIO_STRAND_IMPLEMENTATIONS)
enum { num_implementations = BOOST_ASIO_STRAND_IMPLEMENTATIONS };
#else // defined(BOOST_ASIO_STRAND_IMPLEMENTATIONS)
enum { num_implementations = 193 };
#endif // defined(BOOST_ASIO_STRAND_IMPLEMENTATIONS)
// Pool of implementations.
scoped_ptr<strand_impl> implementations_[num_implementations];