views:

414

answers:

4

Nginx uses epoll, or other multiplexing techniques(select) for its handling multiple clients, i.e it does not spawn a new thread for every request unlike apache.

I tried to replicate the same in my own test program using select. I could accept connections from multiple client by creating a non-blocking socket and using select to decide which client to serve. My program would simply echo their data back to them .It works fine for small data transfers (some bytes per client)

The problem occurs when I need to send a large file over a connection to the client. Since i have only one thread to serve all client till the time I am finished reading the file and writing it over to the socket i cannot resume serving other client.

Is there a known solution to this problem, or is it best to create a thread for every such request ?

A: 

For background this may be useful reading http://www.kegel.com/c10k.html

dangerousdave
A: 

thanks man, but it does not answer my specific question

xask
@xask, you should delete this "answer" as it is not an answer... instead use the "add comment" mechanism to add a comment to any real answers. I'll also note that @dangerousdave's answer really *is* a pretty good answer to your specific question, but unfortunately it involves a high learning curve... see my answer for an alternative.
Peter Hansen
+1  A: 

The simplest approach is to create a thread per request, but it's certainly not the most scalable approach. I think at this time basically all high-performance web servers use various asynchronous approaches built on things like epoll (Linux), kqueue (BSD), or IOCP (Windows).

Since you don't provide any information about your performance requirements, and since all the non-threaded approaches require restructuring your application to use these often-complex asynchronous techniques (as described in the C10K article and others found from there), for now your best bet is just to use the threaded approach.

Please update your question with concrete requirements for performance and other relevant data if you need more.

Peter Hansen
+1  A: 

When using select you should not send the whole file at once. If you e.g. are using sendfile to do this it will block until the whole file has been sent. Instead use a small buffer, and send a little data at a time to each client. Then use select to identify when the socket is again ready to be written to and send some more until all data has been sent. This will allow you to handle multiple clients in parallel.

Chris