繁体   English   中英

我什么时候必须使用boost :: asio:strand

[英]When do I have to use boost::asio:strand

阅读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?

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

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

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

仅从一个线程调用io_service::run()将使所有事件处理程序在该线程中执行,而不管有多少线程正在调用Connection::write(...) 因此,在没有可能并发执行处理程序的情况下,这是安全的。 文档将其称为隐式链

另一方面,如果多个线程正在调用io_service::run() ,那么将需要一个子线程。 这个答案涵盖了更多的细节。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM