I/O objects such as sockets and streams [*are not thread-safe]. Although it is possible to have more than one operation outstanding (for example, a simultaneous asynchronous read and asynchronous write) the stream object itself may only be accessed from one thread at a time. This means that member functions such as move constructors, destructors, or initiating functions must not be called concurrently. Usually this is accomplished with synchronization primitives such as a [@https://en.cppreference.com/w/cpp/thread/mutex `mutex`], but concurrent network programs need a better way to access shared resources, since acquiring ownership of a mutex could block threads from performing uncontended work. For efficiency, networking adopts a model of using threads without explicit locking by requiring all access to I/O objects to be performed within a [@boost:/doc/html/boost_asio/overview/core/strands.html ['strand]].
I/O objects such as sockets and streams [*are not thread-safe]. Although it is possible to have more than one operation outstanding (for example, a simultaneous asynchronous read and asynchronous write) the stream object itself may only be accessed from one thread at a time. This means that member functions such as move constructors, destructors, or initiating functions must not be called concurrently. Usually this is accomplished with synchronization primitives such as a [@https://en.cppreference.com/w/cpp/thread/mutex `mutex`], but concurrent network programs need a better way to access shared resources, since acquiring ownership of a mutex could block threads from performing uncontended work. For efficiency, networking adopts a model of using threads without explicit locking by requiring all access to I/O objects to be performed within a [@boost:/doc/html/boost_asio/overview/core/strands.html ['strand]].