Optimal multithread model
christophe at meessen.net
Tue Mar 16 15:24:32 CET 2010
sorry to have woken the thread troll. It sounds like a very passionate
My rationale is to favor code simplicity and clarity at the cost of some
potential performance penalty. This led me to the leader/follower
pattern with worker threads handling each request independently.
I was considering using libev as a portable replacement of epoll or
kevent which would straightforwardly do the job, but apparently it isn't
Marc Lehmann a écrit :
> I would experiment by simply handing the event loop to the next
> thread in each callback, and acquiring the loop back once finished
> (stopping/starting of watchers is required here).
I'm not sure I understood this correctly. Do you mean I should put the
leader/follower polka inside the callback ? This implies the different
worker threads call the ev_loop, but just when all the others are
inactive, and then in the callback, just synchronize themselves so that
only one thread returns from the callback.
I don't understand how this can work because we end up with multiple
threads executing the ev_loop. This doesn't seem safe because the
threads may have context information on their stack on the current
ev_loop function which may become incoherent. Did I misunderstood your
> That way your callbacks would compete for the event loop, and the event
> loop would only poll once all current callbacks have been invoked - before
> each (or each slow) callback, the event loop would be passed to the next
Isn't that the same as calling ev_loop with the ONE_SHOT flag ?
Here is an optimized version of the previous skeleton code in which I
now use the follower and leader keywords where they belong. I expect
this to be a better use of the ev_loop(ONE_SHOT).
notify() is only called when the leader thread leaves the ev_loop loop
and is about to process a request.
while( !done )
// follower thread pool
while( has_leader_thread )
wait_follower_notification(); // done with a condition
// leader thread task
if( !done )
has_leader_thread = true;
do ev_loop( ONE_SHOT );
while( (!has_pending_requests() || follower_count == 0)
&& !done )
has_leader_thread = false;
// process pending requests in parallel
while( has_pending_requests() )
More information about the libev