Boost ASIO:我们是否需要继续使用async_read并在async_read调用的函数内写入?

时间:2013-04-16 01:08:38

标签: c++ boost boost-asio

我一直试图理解boost http server 3 example中的逻辑。此示例中的请求在connection.cpp中读取,在start()方法中调用:

socket_.async_read_some(boost::asio::buffer(buffer_),
      strand_.wrap(
        boost::bind(&connection::handle_read, shared_from_this(),
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred)));

请注意,async_read_some方法为documented to return immediately。然后在读处理程序(connection::handle_read())内部,如果parse返回boost::indeterminate,我们可能再次调用async_read_some。鉴于我们已经知道我们正在一个单独的线程中工作,这提供了超过socket_.read_some(buffer)的好处。我问的原因是我想要根据需要更改消息解析以调用read_some,但我想到的方法不适用于异步读取。

另外,一个相关问题:

之间是否有任何区别

async_read_some()

boost::thread th([](){ ret = read_some(); handle_read(ret) });

1 个答案:

答案 0 :(得分:2)

Boost.Asio的HTTP Server 3示例的编码方式使其与线程池的大小保持无关。因此,无法保证在单独的线程中完成工作。然而,不可知的好处是它可以通过更多连接进行更好的扩展。例如,考虑检查同时连接的10000个客户端的C10K problem。同步解决方案可能会遇到10000个客户端的各种性能问题或资源限制。此外,异步特性有助于使程序与网络中的行为变化隔离。例如,考虑具有3个客户端和2个线程的同步程序,但是由于网络上的噪声增加,其中2个客户端具有高延迟。如果阻止两个线程等待来自其他客户端的数据,则第三个客户端可能会无意中受到影响。

如果存在少量且有限数量的连接,并且每个连接由一个线程提供服务,则同步和异步服务器之间的性能差异可能最小。在可能的情况下,通常建议避免混合异步和同步编程,因为它可以将复杂的解决方案变成复杂的解决方案。此外,大多数同步算法可以异步写入。

异步操作和同步操作之间存在两个主要差异(即使是在专用线程中运行的那些):

  • 线程安全。如documentation中所述:

      

    通常,并行使用不同的对象是安全的,但是并发使用单个对象是不安全的。

    因此,即使在其自己的线程内调用操作,也无法在同步操作进行时安全地启动异步和同步操作。这在半双工协议中可能是最小的,但应考虑使用全双工协议。

  • 取消操作的能力。如this回答中所述,无法通过Boost.Asio提供的cancel()成员函数取消同步操作。相反,应用程序可能需要使用较低级别的机制,例如信号。