Galimov Albert
Galimov Albert

Reputation: 7357

asio::use_future and event loop

Im browsing asio feature use_future, reading the source code.

But cannot figure out how it works. Say, if i call

auto fut = async_write(sock, buffer, use_future)

fut becomes std::future (according to source code). Now, if i call fut.get() i should able to wait async operation complete and get return value. In the use_future.hpp file i see standard for asio async_result handler resolution and so on..

But if i block on future::get() call, how the IO loop continue to work so operation can complete? Does it create a system thread?

Upvotes: 1

Views: 4562

Answers (2)

Tanner Sansbury
Tanner Sansbury

Reputation: 51881

The Asio tutorial mentions that for single-threaded applications, one may observe poor responsiveness if handlers take a long time to complete. In this case, if only one thread is processing the io_service, then one would observe a deadlock.

When boost::asio::use_future is used, the initiating operation will:

  • initiate the underlying operation with a completion handler that will set the value or error on a std::promise
  • return to the caller a std::future associated with the std::promise.

If a single thread is processing the I/O service, and it blocks on future::get(), then the completion handler that would set the std::promise will never be invoked. It is the application's responsibility to prevent this from occurring. The official futures example accomplishes this by creating an additional thread that is dedicated to processing the I/O service and waits on std::future from within a thread that is not processing the I/O service.

// 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.

Upvotes: 6

sehe
sehe

Reputation: 392999

Does it create a system thread?

No. You're supposed free to decide on which thread(s) to run io_service::run

Upvotes: 1

Related Questions