0

我一直在尝试理解 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 方法被记录为立即返回。然后在读取处理程序 ( connection::handle_read()) 中,如果 parse 返回,我们可能会再次调用 async_read_some boost::indeterminatesocket_.read_some(buffer)鉴于我们已经知道我们在一个单独的线程中工作,这有什么好处。我问的原因是我想更改消息解析以按需调用 read_some ,但我想到的方法不适用于异步读取。

另外,一个相关的问题:两者之间有什么区别吗?

async_read_some()

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

4

1 回答 1

3

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

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

异步操作和同步操作(即使是在专用线程中运行的操作)之间有两个主要区别:

  • 线程安全。如文档中所述:

    一般来说,并发使用不同的对象是安全的,但并发使用单个对象是不安全的。

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

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