The asio::io_context constructor takes an optional concurrency hint that skips some internal locks when only a single thread will interact with the io_context or associated IO objects (or synchronization between threads is already done in the calling code).
My understand is that 1 will allow me to call io_context::run() in one thread and interact normally with the io_context (i.e., all methods except reset() and run(), run_one() etc.) and all associated IO objects.
Additional, with ASIO_CONCURRENCY_HINT_UNSAFE_IO, calling any IO method on IO objects (number 3 in the example below) is illegal and calling any method on the io_context itself is illegal with ASIO_CONCURRENCY_HINT_UNSAFE. Is this correct?
#include <asio/io_context.hpp>
#include <asio/ip/tcp.hpp>
#include <chrono>
#include <iostream>
#include <thread>
static const char msg[] = "Hello World\n";
int main() {
const auto concurrency_hint = ASIO_CONCURRENCY_HINT_1;
asio::io_context ctx{concurrency_hint};
asio::ip::tcp::acceptor acc(ctx, asio::ip::tcp::endpoint(asio::ip::address_v4::any(), 7999));
acc.listen(2);
asio::ip::tcp::socket peer(ctx);
acc.async_accept(peer, [&peer](const asio::error_code &error) {
// call async methods from the thread running the io context (1)
peer.async_write_some(
asio::const_buffer(msg, 12), [&](const asio::error_code &error, std::size_t len) {
peer.close();
});
});
std::thread io_thread([&ctx]() { ctx.run(); });
// call `post()` from another thread (2)
asio::post([]() { std::cout << msg << std::flush; });
// call `async_accept` for an IO object running on another thread (3)
acc.async_accept([&](const asio::error_code &error, asio::ip::tcp::socket peer) {
peer.close();
});
// call `run()` while another thread is already doing so (4)
ctx.run_for(std::chrono::seconds(2));
std::this_thread::sleep_for(std::chrono::seconds(5));
// Call `io_context::stop()` from another thread (5)
ctx.stop();
io_thread.join();
return 0;
}
1 |
UNSAFE |
UNSAFE_IO |
SAFE |
|
|---|---|---|---|---|
| IO methods, same thread (1) | ✔ | ✔ | ✔ | ✔ |
post() from another thread (2) |
✔ | ✖ | ✔ | ✔ |
| IO methods, another thread (3) | ✔? | ✖ | ✖ | ✔ |
run() from two threads (4) |
✖ | ✖ | ✖ | ✔ |
io_context::stop() from another thread (5) |
? | ✖ | ✖ | ✔ |