asio strand和数据同步

时间:2013-02-08 07:55:50

标签: boost-asio

我发现asio关于strand同步的文档很模糊。它只是说在线程池设计asio应用程序中,处理程序可以在任何调用io_service::run()的线程中运行。使用strand来扭曲这些处理程序可以使它们的执行正确并发。在example3中,所有handle_read都由strand换行,我认为Connection类中的变量(例如buffer)已由strand同步},不同的线程调用handle_read将获取最新数据,即可。但是,在Connection类中定义的数据成员也可以由strand包裹,它也由处理程序访问?我认为这是一个问题,不是吗?

在其文档example3中,为什么handle_accept没有被strand包裹?多线程访问new_connection_:线程A调用new_connection_.reset,线程B调用server::handle_accept。我认为这需要数据同步,否则线程B可能会使用日期new_connection_尚未调用其重置。

2 个答案:

答案 0 :(得分:1)

我认为你在某种程度上忽略了 strand 的含义。 它不同步数据访问。它同步处理程序调用。这可以理解为“由给定的 strand 包裹的所有处理程序不会被同时调用”。

所以,你的第一个任务:如果某个处理程序没有被strand包裹 - 它现在可以同时调用。所以它的主题是同步问题和/或RC。请注意,如果您在一个地方包装并不意味着您受到RC的保护;这应该在每次通话中完成。除非你使用.wrap

,否则strand不知道你从其他线程调用什么

第二个问题:在给定示例中 start_accept 设置接受处理程序 handle_accept handle_accept 设置新的接受处理程序(通过调用 start_accept )。因此,它们不会同时调用,因为您无法创建2个或更多 async_accept 事件。当然,如果其他线程为同一个“服务器”实例调用 start_accept - 这个例子可以/将会失败,但这样做是明显的错误。

答案 1 :(得分:1)

HTTP Server 3 的设计方式实际上并不需要strand

Boost.Asio的一个基本特征是,对于给定的操作,最多只调用一次处理程序。这种行为允许异步编程的调用路径更多地被设想为调用链。

例如,检查server接受连接的插图调用链:

server::server(...)
{
  start_accept();  --.
}                    |
    .----------------'
    |      .----------------------------------------.
    V      V                                        |
void server::start_accept()                         |
{                                                   |
  new_connection_.reset(new connection(...));       |
  acceptor_.async_accept(..., handle_accept);  --.  |
}                                                |  |
    .--------------------------------------------'  |
    |                                               |
    V                                               |
void server::handle_accept(...)                     |
{                                                   |
  if (!error)                                       |
  {                                                 |
    new_connection_->start();                       |
  }                                                 |    
  start_accept();  ---------------------------------'
}

如图所示,只存在一个异步事件链。由于不可能在new_connection上同时执行处理程序或操作,因此它被称为在隐式链中运行。处理程序server::handle_accept运行的线程无关紧要。

this问题中回答了connection::handle_read个调用链以及有关股的更多详细信息。