ev_async_send() not trigerring corresponding async handler in target loop ?

Pierre-Yves Kerembellec py.kerembellec at gmail.com
Tue Dec 29 16:37:16 CET 2009


>> Your experience is interesting, but I have a question: why do you need
>> threads in event-driven machine? I just tested my app based on libev,
>> it works as followed:
>> 
>> bind();
>> listen();
>> 
>> for (i = 0; i < 4; ++i)
>> {
>>   switch (fork())
>>   {
>>   case -1: /* epic fail */ break;
>>   case  0: return run_loop();
>>   default: /* manage worker (ev_child_init, ev_child_start etc) */
>>   }
>>   /*
>>    * Watch workers
>>    */
>>   ev_loop();
>> }
>> 
>> int run_loop(void)
>> {
>>   /*
>>    * Ignore all signals as master process will manage them itself.
>>    * Do accept() which is managed by kernel instead of master
>>    * process.
>>    */
>>   ev_loop();
>> }
>> 
>> With this model I get about 17k req/s (including HTTP/1.0 protocol
>> parsing) on 4 CPU server.
> 
> These threads are "worker threads", and there are several of them because a single threaded program would
> only use one core on a multi-way server. In your example above, you replaced thread by processes (which is
> barely the same on Linux for instance).
> 
> Also, the small HTTP server stub was just an example of code to pinpoint concurrency problems, understand
> where the fds were being lost and get an estimation of performance (and most importantly use "ab"). My worker
> threads will in fact perform much more operations at each request, including memory structure manipulation
> and disk I/O (which may block a little). Threading (or forking) is then necessary to avoid one particular client
> processing to stuck the entire clients stack.

Ooops, just realized something else in your email: you're actually forking _after_ bind()/listen() (which is fine) and
all child processes are adding the listening socket to their own event loop (in an ev_io handler I guess) ? Does it work
correctly ? I mean I'm pretty sure that when a connection is presented to the listening socket, all processes wake-up
but only one accept() succeed and the others fail with negative status (this situation is probably handled in your code
right) ? In other terms, your accept_cb() is probably like this:

void accept_cb()
{
    if (accept(...) < 0)
    {
        return;
    }
}

Or is the "ev_loop()" pictured in your code above refering to the "ev_default_loop()" ?

Cheers,
Pierre-Yves




-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.schmorp.de/pipermail/libev/attachments/20091229/9a7af758/attachment.html>


More information about the libev mailing list