asio strand为什么比mutex好

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];


你可能感兴趣的:(asio strand为什么比mutex好)