In the boost asio documentation for strands it says:
Strands may be either implicit or explicit, as illustrated by the following alternative approaches:
- ...
- Where there is a single chain of asynchronous operations associated with a connection (e.g. in a half duplex protocol implementation like HTTP) there is no possibility of concurrent execution of the handlers. This is an implicit strand.
- ...
However, in boost beast's example for a multithreaded asynchronous http server the boost::asio::ip::tcp::acceptor
as well as each boost::asio::ip::tcp::socket
get their own strand explicitly (see line 373 and 425). As far as I can see, this should not be necessary, since all of these objects are only ever going to be accessed in sequentially registered/running CompletionHandler
s.¹ Precisely, a new async operation for one of these objects is only ever registered at the end of a CompletionHandler
registered on the same object, making any object be used in a single chain of asynchronous operations.²
Thus, I'd assume that - despite of multiple threads running concurrently - strands could be omitted all together in this example and the io_context
may be used for scheduling any async operation directly. Is that correct? If not, what issues of synchronization am I missing? Am I misunderstanding the statement in the documentation above?
¹: Of course, two sockets or a socket and the acceptor may be worked with concurrently but due to the use of multiple stand
s this is not prevented in the example either.
²: Admittedly, the CompletionHandler
registered at the end of the current CompletionHandler
may be started on another thread before the current handler actually finished, i. e. returns. But I would assume that this is not a circumstance risking synchronization problems. Correct me, if I am wrong.