asio :: use_future和事件循环
正在浏览asio功能use_future,阅读source code。asio :: use_future和事件循环
但无法弄清楚它是如何工作的。说,如果我打电话
auto fut = async_write(sock, buffer, use_future)
fut
变得std::future
(根据源代码)。现在,如果我打电话fut.get()
我应该能够等待异步操作完成并获得返回值。在use_future.hpp
文件中,我看到asio async_result
处理程序分辨率等标准。
但是,如果我阻止future::get()
调用,IO循环如何继续工作,以便操作可以完成?它是否创建一个系统线程?
的短耳tutorial提到,对于单线程应用程序,可以观察反应很差,如果处理程序需要很长时间才能完成。在这种情况下,如果只有一个线程正在处理io_service
,那么会发现死锁。
当使用boost::asio::use_future
,发起动作:
- 发起底层操作用,将设置在
std::promise
- 返回到与相关联的主叫方一个
std::future
的值或误差完成处理程序std::promise
。
如果一个线程处理I/O服务,它阻止在future::get()
,然后完成处理程序将设置std::promise
将永远不会被调用。防止这种情况发生是应用程序的责任。 official futures example通过创建一个专用于处理I/O服务的附加线程并在不处理I/O服务的线程内等待std::future
来实现此目的。
// We run the io_service off in its own thread so that it operates
// completely asynchronously with respect to the rest of the program.
boost::asio::io_service io_service;
boost::asio::io_service::work work(io_service);
std::thread thread([&io_service](){ io_service.run(); });
std::future<std::size_t> send_length =
socket.async_send_to(..., boost::asio::use_future);
// Do other things here while the send completes.
send_length.get(); // Blocks until the send is complete. Throws any errors.
它是否创建系统线程?
号你
应该
免费哪个线程(S)上决定运行io_service::run
的[特定平台实现说明](http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/overview/implementation.html)列出了所有内螺纹。这个[demo](http://coliru.stacked-crooked.com/a/d85347255e8d84dd)表明即使操作系统操作完成,如果'io_service'没有得到处理,那么promise也不会被满足。 –
所以问题是:如果我在'future :: get'调用中只有1个线程和它的阻塞,其中'io_service :: run'被处理以便调用'promise_handler'? – PSIAlt
这更有意义。但是如果在处理程序中使用'use_future',那么'io_service :: run'调用了什么呢?这将再次陷入僵局。看起来这个功能并不像我看起来那么安全=( – PSIAlt
@PSIAlt)在处理程序中无限期阻塞的调用函数很少安全。当我使用'use_future'时,我只在没有处理I/O服务的线程中使用它,并且这些线程启动的所有异步操作都使用'use_future'。这种方法没有用户处理程序,可以在其中调用阻塞调用 –
,但这也意味着您应该使用每个连接的线程来使此模式有效。我会更好地坚持yield_context,它似乎更容易扩展。 – PSIAlt