本文介绍了我什么时候使用boost :: ASIO:股的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 无效连接::写(提高:: shared_ptr的<串GT; MSG)
{
    _io_service.post(升压::绑定(安培;连接:: _ do_write,对此,味精));
}无效连接:: _ do_write(提升:: shared_ptr的<串GT; MSG)
{
    如果(_write_in_progress)
    {
      _msg_queue.push_back(MSG);
    }
    其他
    {
      _write_in_progress = TRUE;
      提高:: ASIO :: async_write(_socket,提高:: ASIO ::缓​​冲区(*(msg.get()))
      提高::绑定(安培;连接:: _ handle_write,为此,
             提高:: ASIO ::占位符::错误));
    }
}无效连接:: _ handle_write(的boost ::系统::错误_ code常量和放大器;错误)
{
  如果(!错误)
  {
    如果(!_ msg_queue.empty())
    {
          提高:: shared_ptr的<串GT;味精= _msg_queue.front();
      _msg_queue.pop_front();
      提高:: ASIO :: async_write(_socket,提高:: ASIO ::缓​​冲区(*(msg.get()))
           提高::绑定(安培;连接:: _ handle_write,为此,
                   提高:: ASIO ::占位符::错误));
        }
    其他
    {
      _write_in_progress = FALSE;
    }
  }
}

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


解决方案

简短的回答:不,你没有在这种情况下,使用

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

注意:这个解释可能是过于简单和技术上的不准确的,但它给在 io_service对象和的

Reading the document of boost::asio, it is still not clear when I need to use asio::strand. Suppose that I have one thread using io_service is it then safe to write on a socket as follows ?

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

Where multiple threads calls Connection::write(..) or do I have to use asio::strand ?

解决方案

Short answer: no, you don't have to use a strand in this case.

Broadly simplificated, an io_service contains a list of function objects (handlers). Handlers are put into the list when post() is called on the service. e.g. whenever an asynchronous operation completes, the handler and its arguments are put into the list. io_service::run() executes one handler after another. So if there is only one thread calling run() like in your case, there are no synchronisation problems and no strands are needed.
Only if multiple threads call run() on the same io_service, multiple handlers will be executed at the same time, in N threads up to N concurrent handlers. If that is a problem, e.g. if there might be two handlers in the queue at the same time that access the same object, you need the strand.
You can see the strand as a kind of lock for a group of handlers. If a thread executes a handler associated to a strand, that strand gets locked, and it gets released after the handler is done. Any other thread can execute only handlers that are not associated to a locked strand.

Caution: this explanation may be over-simplified and technically not accurate, but it gives a basic concept of what happens in the io_service and of the strands.

这篇关于我什么时候使用boost :: ASIO:股的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-14 19:41