CppCon 2016: Michael Caisse “Asynchronous IO with Boost.Asio"
Why Stack Overflow recommends it
Stack Overflow users link it as the go-to explanation of how Asio works under the hood, especially connection lifetime with shared_ptr, strands, and why you must not issue overlapping async writes.
Recommended by 5 people across 9 different months, 2017 to 2022.
What it is
A CppCon 2016 talk by Michael Caisse introducing Boost.Asio for building reactive systems without piles of waiting threads. He covers how the io_service and handlers work, shows best practices, and builds a simple TCP client and server.
What people said
Strong rec kenba · 2017-04 · Stack Overflow · on “How to design proper release of a boost::asio socket or wrapper thereof”
Connection lifetime is a fundamental issue with boost::asio . Speaking from experience, I can assure you that getting it wrong causes "undefined behaviour"... The asio examples use shared_ptr to ensure that a connection is kept alive whilst it may have outstanding handlers in an asio::io_service . Note that even in a single thread, an asio::io_service runs asynchronously to the application code, see CppCon 2016: Michael Caisse "Asynchronous IO with Boost.Asio" [this video] for an excellent description of the precise mechanism. A shared_ptr enables the lifetime of a connection to be controlled by the shared_ptr instance count. IMHO it's not "cheating and cheating big"; but an elegant solution to c
Strong rec kenba · 2019-10 · Stack Overflow · on “Boost.Asio functions under the hood”
See CppCon 2016: Michael Caisse "Asynchronous IO with Boost.Asio" [this video] for an excellent description of how asio works.
Recommends kenba · 2017-04 · Stack Overflow · on “How is networking implemented in the Boost Library”
For a simple description of how asio is implemented, see CppCon 2016: Michael Caisse "Asynchronous IO with Boost.Asio" [this video]
Recommends kenba · 2017-05 · Stack Overflow · on “multiple boost io_service for multiple network cards on separate threads”
Instead of using an io_service in a thread per pair of network cards, you may be better off wrapping your sockets in an asio::io_service::strand and using a single io_service in a thread pool, see: Strands: Use Threads Without Explicit Locking [LINK] and Asynchronous IO with boost asio [this video] . It is easiest to put the sockets and strands together in a class as in this example: Timer 5 example [LINK] . There is some code that supports asio UDP sockets and strands here [LINK] .
Recommends kenba · 2017-08 · Stack Overflow · on “Multiple Boost::ASIO async_send_to in one go”
No, you cannot safely call async_send_to multiple times in a row WITHOUT waiting for the write handler to be called. See Asynchronous IO with Boost.Asio [this video] to see precisely why. However, asio supports scatter gather [LINK] and so you can call async_send_to with multiple buffers, e.g.: typedef std::deque<boost::asio::const_buffer> ConstBuffers; std::string msg_1("Blah"); ... std::string msg_n("Blah"); ConstBuffers buffers; buffers.push_back(msg_1); ... buffers.push_back(msg_n); socket_.async_send_to(buffers, tx_endpoint_, write_handler); So you could increase your throughput by double buffering your message queue and using gathered writes...
Recommends kenba · 2018-07 · Stack Overflow · on “When are threads created when calling async functions of boost.asio?”
The Proactor design Pattern: Concurrency Without Threads [LINK] describes how `boost::asio` implements concurrency. This video [this video] explains it very nicely.
Recommends Superlokkus · 2019-02 · Stack Overflow · on “Broken pipe after writing to socket”
I assume you had to do this because of broken life times, as an real life example I can refer to my project [LINK] , but in general I recommend [this video] i.e. [LINK]
Recommends Doss Gunter · 2020-04 · Stack Overflow · on “Creating thread bound to io_service inside a struct”
As you suspected you are missing some key points about ASIO. You state you desire for each ApplicationPair to have its own thread on the io_service. This is not really how it works. Once you call io_service.run() on a thread that thread is now owned by the io_service. The io_service will schedule events as it sees fit. Think of it more like a thread pool, you post task to the io_service and it schedules them to the pool. Also, you should look at strands. This is like the ASIO version of a mutex. It functions similarly, but is conceptually different. boost::asio strand example [LINK] This may not seem important here because you are not reading to or writing from variables, however std::cout i
Recommends lakeweb · 2020-08 · Stack Overflow · on “How to use boost::beast, download a file no blocking and with responses”
I've updated this as I finally put it to use and I wanted the old method where I could download to a file or a string. Link to how asio works, great talk. CppCon 2016 Michael Caisse Asynchronous IO with BoostAsio [this video] As for my misunderstanding of how to pass a lambda, here is Adam Nevraumont's answer [LINK] There are two ways to compile this using a type to select the method. Both are shown at the beginning of main . You can construct either a file downloader or string downloader by selecting the type of beast parser. The parsers don't have the same constructs so an if constexpr compile time conditions are used. And I checked, a release build of the downloader is about 1K so pretty light
Recommends Drejc · 2022-02 · Stack Overflow · on “How to ensure that the messages will be enqueued in chronological order on multithreaded Asio io_service?”
Following Michael Caisse's cppcon talk [this video] I created a connection handler MyUserConnection which has a sendMessage method. sendMessage method adds a message to the queue similarly to the send() in the cppcon talk. My sendMessage method is called from multiple threads outside of the connection handler in high intervals. The messages must be enqueued chronologically. When I run my code with only one Asio io_service::run call (aka one io_service thread) it async_write 's and empties my queue as expected (FIFO), however, the problem occurs when there are, for example, 4 io_service::run calls, then the queue is not filled or the send calls are not called chronologically . class MyUserConnecti