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