我什么时候必须使用boost :: ASIO:链(When do I have to use boo

2019-09-02 02:23发布

阅读的boost :: ASIO的文件,它仍然是不明确的,当我需要使用ASIO ::链。 假设我有使用io_service对象是那么安全套接字上写如下一个线程?

void Connection::write(boost::shared_ptr<string> msg)
{
    _io_service.post(boost::bind(&Connection::_do_write,this,msg));
}

void Connection::_do_write(boost::shared_ptr<string> msg)
{
    if(_write_in_progress)
    {
      _msg_queue.push_back(msg);
    }
    else
    {
      _write_in_progress=true;
      boost::asio::async_write(_socket, boost::asio::buffer(*(msg.get())),
      boost::bind(&Connection::_handle_write,this,
             boost::asio::placeholders::error));
    }
}

void Connection::_handle_write(boost::system::error_code const &error)
{
  if(!error)
  {
    if(!_msg_queue.empty())
    {
          boost::shared_ptr<string> msg=_msg_queue.front();
      _msg_queue.pop_front();
      boost::asio::async_write(_socket, boost::asio::buffer(*(msg.get())),
           boost::bind(&Connection::_handle_write,this,
                   boost::asio::placeholders::error));
        }
    else
    {
      _write_in_progress=false;
    }
  }
}

当多个线程调用连接::写(..)或者我必须使用ASIO ::搁浅?

Answer 1:

简短的回答:不,你不必使用strand在这种情况下。

广义simplificated,一个io_service包含函数对象(句柄)的列表。 处理程序被放入列表时post()被调用的服务。 例如,每当一个异步操作完成,处理程序和它的参数放入列表中。 io_service::run()相继执行一个处理程序。 因此,如果只有一个线程调用run()像你的情况,有没有同步的问题,没有strand都需要秒。
只有当多个线程调用run()在同一个io_service ,多个处理程序将在同一时间执行,在N个线程最多N个并发处理程序。 如果这是一个问题,例如,如果有可能是在访问同一对象同时排队两个处理程序,你需要的strand
你可以看到strand作为一种锁的一组处理程序。 如果一个线程执行关联到一个处理程序strand ,这strand被锁定,处理程序完成后得到释放。 任何其他线程可以执行只有那些没有关联到锁定的处理程序strand

注意:这个解释可能是过于简化和技术上不准确的,但它给在发生什么的一个基本概念io_service和的strand秒。



Answer 2:

调用io_service::run()距离只有一个线程将导致所有事件处理程序的线程中执行的,无论有多少线程调用, Connection::write(...) 因此,处理程序没有可能并发执行,它是安全的。 该文件称此为一个隐含链 。

在另一方面,如果将多个线程调用io_service::run() ,然后将股成为必需。 这个答案涵盖了更多的细节股。



文章来源: When do I have to use boost::asio:strand