When writing multithreaded programs that work with sockets, a common pattern is to have two threads per socket—one thread writes the data to the socket, another one reads the data. Obviously, the socket library used for this should be threadsafe to start with and support a read from a socket in one thread and a write to the socket in the other thread without corrupting the library’s socket state. The raw system calls read() and write() support this. Your experience with the more sophisticated libraries may vary.
The write thread may be implicit: It may be just a mutex that allows any thread to write into a socket without interference from other threads. But reading is different. It’s asynchronous, with data supplied by the other side. It’s impossible to predict when the data will come in. Even if the remote side never sends any data, having a reading thread is still useful to detect a dropped connection. Otherwise, if only the return codes of writing are checked, the connection drop won’t be detected until the next write, and that might be a while. It might never be detected if the application has no new data to send to the socket. Such sloppy implementations are surprisingly common—you can identify these applications by lots of half-closed sockets sitting around in the operating system.


