>> 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




_______________________________________________
libev mailing list
libev@lists.schmorp.de
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev

Reply via email to