But using them requires synchronization, locking and others. People who have used them may realize that some times it becomes a nightmare to trace a problem/crash.
One can still process multiple client request in a single thread, without blocking on the request. This is achieved by using event driven programing.
How to do
1. Use event notifiers such as poll/select/epoll/kqueue
2. Put your connections (i.e the socket file descriptors ) in non-blocking mode.
By doing so you do not wait for the entire data to be written or the entire data to be read at one go. You will read/write in chunk if buffer space or data is available else you can go a head doing other works like process the other client requests, by putting the current connection back into event notifier.
3. Maintain state information, in order to take appropriate action when a event takes place. Unlike the multi threaded, where a single thread as sequential logic.In event driven you will process a connection when a event occurs, for this you need to keep track about the state in which you left it last time.
4. Minimize the use of systems call or your code which can go into blocking, to avoid starvation of other connections.
Advantages
1. It saves the time in context switching, due to threads/process getting scheduling.
2. Saves the trouble of maintaining locking/synchronization (you may still have to use them in event driven programing, but to a small extent)