Hello,
sorry to have woken the thread troll. It sounds like a very passionate
discussion topic.
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
as simple.
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
proposal ?
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
thread.
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.
worker_thread_function(...)
{
while( !done )
{
// follower thread pool
follower_count++;
while( has_leader_thread )
wait_follower_notification(); // done with a condition
variable
follower_count--;
// 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;
}
notify_follower();
// process pending requests in parallel
while( has_pending_requests() )
process_request();
}
}
_______________________________________________
libev mailing list
libev@lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev