2015-12-01 90 views
0

我是一个加速C++的新手,并用它来写一个类似服务器的应用程序,我想知道是否有可能同时使用boost::asio::ip::tcp::socket::async_read_some(...)boost::asio::ip::tcp::socket::write_some(...)使用boost ::短耳插座异步和同步操作一起

我的方案的Connection对象通过持续监听:

void Connection::doRead() 
{ 
    auto self(shared_from_this()); 
    socket_.async_read_some(boost::asio::buffer(data_rx_, max_length), 
     [this, self](boost::system::error_code ec, std::size_t length) 
     { 
      if (!ec) 
      { 
       afterReading(length); 
       doRead(); 
      } 
     }); 
} 

同时,异步回调函数(在不同的线程中运行)可以调用socket_.read_write而连接是“阅读”。

我已经阅读过各种Boost :: Asio文档,但是这种情况从未涉及。

这是允许的吗?如果不是,应该怎么做才能避免它?

编辑:

我已阅读,所建议的,各种答案包括这样:Why do I need strand per connection when using boost::asio?,但因为它是不是阉混合异步和同步(通过不同的线程调用)规定仍然无法找到答案要求是安全与否。

+1

This [answer](http://stackoverflow.com/a/12801042/1053968)可能会有所帮助。 –

+0

@TannerSansbury是正确的,而且这可能只是作为一个副本被关闭。你需要使用股票,当客户端没有在听时,写入客户端肯定没有任何意义,但是写作很繁忙。 –

+0

可能的重复[为什么我需要链每个连接时使用boost :: asio?](http://stackoverflow.com/questions/12794107/why-do-need-strand-per-connection-when-using -boostasio) –

回答

1

这是不安全的。

answer进入细节,但总结一下,它是不是安全的多线程拨打电话的同时,与例外,如果操作系统支持多个同步调用可以是安全的。如果一个线程在套接字上启动异步操作,而另一个线程在同一个套接字上执行同步操作,则会落入前一种情况,并且不安全。

最优雅的解决方案是避免混合同步和异步操作。

  • 如果使用同步操作并且操作系统不支持并发同步操作,则执行显式锁定,例如通过使用互斥锁。
  • 如果使用异步操作和多线程,则使用明确的strand来防止并发调用处理程序。

此外,通过利用Boost.Asio对futures的支持,可以同步阻止等待异步操作的完成。这种方法可以允许向用户公开同步阻塞API,但在内部使用异步操作。启动操作(async_*)需要在一个链中调用,如果调用者没有在链的上下文中运行,则需要使用某种形式的同步来允许调用者等待Asio创建未来的目标。