发生哪些线程异步操作



阅读 asio 的文档后,我很清楚完成处理程序是由调用io_serviceio.run()方法的线程之一调用的。但是,我不清楚的是读/写异步方法发生在哪个线程。是我调用方法的线程,还是在调用io.run()方法的线程之一中?或者,在最后一种情况下,库是否在后台创建另一个线程并执行操作?

将在启动async_*函数中尝试 I/O 操作。 如果满足操作的完成条件或发生错误,则操作已完成,完成处理程序将发布到io_service中。 否则,该操作不完整,它将被排队进入io_service,运行io_service函数的应用程序线程poll()poll_one()run()run_one()执行底层的I/O操作。 在这两种情况下,完成处理程序都由处理io_service的线程调用。

async_write()文档指出异步操作可以立即完成:

无论异步操作是否立即完成,都不会从此函数中调用处理程序。处理程序的调用将以等效于 使用boost::asio::io_service::post()的方式执行。

异步操作要求文档中也指出了此行为:

异步操作完成后,将通过以下方式调用该操作的处理程序:

  • 为处理程序构造绑定完成处理程序bch...
  • 调用ios.post(bch)以安排处理程序进行延迟调用...

这意味着不得直接从启动函数中调用处理程序,即使异步操作立即完成也是如此。


下面是演示此行为的完整示例。 在其中,socket1socket2是相连的。 最初,socket2没有可用的数据。 但是,在调用async_write(socket1, ...)后,即使io_service尚未运行,socket2也有数据:

#include <boost/asio.hpp>
constexpr auto noop = [](auto&& ...){};
int main()
{
using boost::asio::ip::tcp;
boost::asio::io_service io_service;
// Create all I/O objects.
tcp::acceptor acceptor{io_service, {{}, 0}};
tcp::socket socket1{io_service};
tcp::socket socket2{io_service};
// Connect sockets.
acceptor.async_accept(socket1, noop);
socket2.async_connect(acceptor.local_endpoint(), noop);
io_service.run();
io_service.reset();
// Verify socket2 has no data.
assert(0 == socket2.available());
// Initiate an asynchronous write.  However, do not run
// the `io_service`.
std::string data{"example"};
async_write(socket1, boost::asio::buffer(data), noop);
// Verify socket2 has data.
assert(0 < socket2.available());
}

例如,您希望将一些数据发送到远程合作伙伴 - 异步。

boost::asio::async_write(_socket, boost::asio::buffer(msg.data(), msg.size()),
std::bind(&Socket::WriteHandlerInternal, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
//Where 'this' is the class Socket

在此之前,您可能已经创建了一个名为ioService.run()的线程。async_write函数将采用与您用于创建套接字相同的ioService。它将其放入ioService的队列中,以执行写入操作和处理程序 -在运行ioService的线程上,正如async_已经建议的那样。

最新更新