【问题标题】:When do I have to use boost::asio:strand我什么时候必须使用 boost::asio:strand
【发布时间】:2013-04-30 03:17:42
【问题描述】:

看了boost::asio的文档,还不清楚什么时候需要用到asio::strand。假设我有一个使用 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;
    }
  }
}

多个线程调用 Connection::write(..) 还是必须使用 asio::strand ?

【问题讨论】:

    标签: c++ multithreading boost boost-asio


    【解决方案1】:

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

    简单地说,io_service 包含函数对象(处理程序)的列表。当在服务上调用post() 时,处理程序被放入列表中。例如每当异步操作完成时,处理程序及其参数都会放入列表中。 io_service::run() 一个接一个地执行一个处理程序。因此,如果只有一个线程调用 run() 就像您的情况一样,则不存在同步问题,也不需要 strands。
    只有当多个线程在同一个io_service 上调用run() 时,才会同时执行多个处理程序,在N 个线程中最多N 个并发处理程序。如果这是一个问题,例如如果队列中可能同时有两个处理程序访问同一个对象,则需要strand
    您可以将strand 视为一组处理程序的一种锁。如果线程执行与strand 关联的处理程序,则strand 将被锁定,并在处理程序完成后被释放。任何其他线程只能执行与锁定的strand 无关的处理程序。

    警告:这种解释可能过于简单,技术上也不准确,但它给出了io_service 和@987654335 中发生的基本概念@s.

    【讨论】:

      【解决方案2】:

      仅从一个线程调用io_service::run() 将导致所有事件处理程序在线程内执行,无论有多少线程调用Connection::write(...)。因此,在处理程序不可能并发执行的情况下,它是安全的。文档将此称为implicit strand

      另一方面,如果多个线程正在调用io_service::run(),则需要使用一个链。 This 回答更详细地涵盖了各个部分。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-22
        • 2020-03-06
        • 2014-11-08
        • 2013-10-23
        • 1970-01-01
        • 2011-03-18
        • 2012-04-26
        相关资源
        最近更新 更多