>> 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
[email protected]
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev