I read the C10K document, as well as many related articles on extending a socket server. All roads indicate the following:
Avoid the classic "thread to join" error.
Prefer epoll over select.
Similarly, the obsolete async io mechanism in unix can be difficult to use.
My simple TCP server just listens for client connections in the listening slot on a dedicated port. Having received a new connection, it analyzes the request and sends a response. Then gracefully closes the socket.
I think I have a good handle on how to scale this on a single thread using epoll. Only one loop that calls epoll_wait for the listening socket, as well as for existing client connections. Upon return, the code will process new creations of new client connections, as well as manage the state of existing connections, depending on which socket has just received the signal. And perhaps some logic for managing connection timeouts, graceful socket closures, and efficient allocation of resources for each connection. Seems simple enough.
But what if I want to scale it to take advantage of multiple threads and multiple processor cores? The basic idea that comes to mind is this:
One dedicated thread to listen for incoming connections in the TCP listening socket. Then a set of N threads (or a pool of threads) to handle all active concurrent client connections. Then come up with some thread-safe way in which the listener thread will βsendβ a new connection (socket) to one of the available worker threads. (ala IOCP on Windows). The workflow will use the epoll loop for all connections it processes to do what a single-threaded approach would do.
Am I on the right track? Or is there a standard design pattern for running a TCP server with epoll for multiple threads?
Suggestions on how the listening thread sends a new connection to the thread pool?
source share