Quote:
Originally Posted by
LittleCookieMon
1. It will run on a modern x86 chip (I7 6700K) which has 4 cores, each running two threads.
Hyperthreading does not work that way. The eight "threads" are not program threads, just a side-effect of how the OS manages the four cores in hyperthreading mode. Four cores, four threads.
Since this is I/O and network related though, those threads may spend a lot of time waiting anyway though.
Quote:
Is fork() too costly for each connection?
Yes.
Quote:
Is kqueue the wrong tool, given that the connections are not really long-lived and do not consist of repeated updates/polling?
They may not be long-lived, but HTTP still means lots of waiting for responses. You can have thousands of threads which spend 99% of their time waiting, or a few threads which spend most of their time working.
That's what makes aggregation routines like select and kqueue efficient. You can watch a set of things, waiting for
any of them to become ready, without wasting time creating surplus threads which all sit around waiting.
Assigning one thread to multiple sockets can be efficient -- you can handle whichever one becomes ready out of a large set and handle it. One thread can do a lot of work in a short amount of time if you don't interrupt them by creating and killing them all the time. You can even do this in a single-threaded approach to make something surprisingly responsive.
Quote:
Should I use a thread approach where I have the master, and then create a new thread for each connection and then terminate the thread after the response is sent back?
That's almost the same problem as creating processes. Don't create a new
anything for each connection.
Quote:
I am really at a loss as to what the most effective approach to take is.
If there was a perfect 'most effective' approach everyone would use it and throw out the rest. Approaches can and do vary.
My approach would be to have one thread which loops on accept() and puts the socket in a queue of some sort, for one of a fixed number of worker threads to grab it from and add it to the pile of sockets each worker thread is communicating with.
If you wanted to build something
minimalistic, how about a single-threaded approach using select or kqueue to respond to connections and I/O as they become ready, rather than first-come-first-serve? People assume it's necessary to multithread to do anything but FCFS these days, but that's not strictly true, especially for lots of short-lived tasks. That's
why a single thread can still be so effective at dealing with lots of small tasks -- given enough work, all the time it'd waste on waiting can actually get used.