Hi Mathieu, I tried Ben's solution in a side-project of mine (which is written in D and inspired by NodeJS). It works but is much slower than the single threaded event loop approach. So even if you get multi-threaded eventloop there is latency added. Also, you need to make some tweaks. Eg: in libev, setting ev_set_io_collect_interval to a higher value so that not all pending events are handled by 1 thread (which is going to take you back to single threaded approach with other threads freely spinning), but instead is handled by as many threads as is available. In libev at least there is no way to specify how many events should be handled in a single iteration (at least that I know of and I guess its the same with libuv too). I think multi-threaded event loop is more cumbersome than just fork() and loop in child process (with Ben's suggestion about making the descriptor inheritable for libuv).
Shripad K On Thu, Aug 30, 2012 at 2:30 AM, Mathieu Garaud <[email protected]>wrote: > Hi Zhang, > > I implemented Ben's solution but I faced exactly the same issue. I mean > even if I pass uv_stream_t over the pipe using uv_write2 the stream is > still attached to the wrong event loop. Hence the callbacks are executed on > the wrong thread. > > However I checked the code at the revision Ben's referred to in one of his > email and I think that if you understand how libev works you > can unregister all the event listeners and move them to the new event loop > on another thread. I'm sorry I didn't go further in my investigation. > > However reading stream.c again I don't remember why the streamServer and > streamClient has to be on the same event loop. > Ben knows probably the reason but if this > assertion<https://github.com/joyent/libuv/blob/master/src/unix/stream.c#L456>wasn't > there I'm pretty sure that we could implement the threading much mor > easier. > > I'm so sorry but I didn't push further my investigations. > > Regards, > > Mathieu > > > > On Wednesday, August 29, 2012 11:15:55 AM UTC+2, Zhang Hu wrote: >> >> Hi Mathieu, >> >> I'm thinking the same problem as you had. If I'm right, nginx's >> work-thread machnism can benifit the multiple CPUs/cores. Nginx listens one >> sockets by multiple processes. >> >> How is your solution doing? >> >> Regards, >> Tiger >> >> On Monday, July 2, 2012 4:28:13 PM UTC+8, Mathieu Garaud wrote: >>> >>> Hi, >>> >>> Thanks for the tip! I'll implement this solution this evening and I'll >>> see if I'm able to increase the number of request/s of this HTTP server can >>> handle. >>> >>> Cheers, >>> >>> Mathieu >>> >>> On Monday, July 2, 2012 3:05:45 AM UTC+2, Ben Noordhuis wrote: >>>> >>>> On Mon, Jul 2, 2012 at 1:39 AM, Mathieu Garaud <[email protected]> >>>> wrote: >>>> > Hello Ben, >>>> > >>>> > Thanks for your quick reply. >>>> > >>>> > I understand that libuv is not thread safe and it's made by design. >>>> I'd like >>>> > to know if we could benefit from the best of both world: multi cores >>>> cpus + >>>> > event based loop without the slow downs and the complexity of >>>> mutexes, >>>> > semaphores ... >>>> > >>>> > Correct me if I'm wrong but the problem of passing stream from one >>>> loop to >>>> > another means implementing a thread safe mechanism, isn't it? >>>> > >>>> > Is there is any other way to implement it? I though that if I could >>>> mark a >>>> > stream (or put in stasis but it seems harder to implement because I >>>> had to >>>> > sync the latent data) then the other loop could import it + register >>>> file >>>> > descriptor with a minimun lock risk or time consumed. This >>>> implementation >>>> > will introduce a limitation one stream will only be able to be >>>> attached to 1 >>>> > loop and it will be async. >>>> > >>>> > Anyway, you probably already think of it trying to implement isolates >>>> > support for node. >>>> >>>> I'm afraid there's no convenient support for in-process sharing of >>>> handles at the moment. What can you do is the following (I'm assuming >>>> you have some kind of TCP server that you want to share across >>>> threads): >>>> >>>> 1. (thread A) create your uv_tcp_t server handle (i.e. bind and listen) >>>> 2. (thread A) create a uv_pipe_t and bind it to a path. >>>> 3. (thread B) connect to the pipe >>>> 4. (thread A) send over the server handle with uv_write2() >>>> 5. (thread B) receive handle and start listening >>>> >>>> In case you're interested, [1] is the commit that removed uv_import() >>>> and uv_export(). In hindsight, it may have been better to leave them >>>> in. >>>> >>>> Then again, the approach outlined above works and has the benefit that >>>> it's intrinsically thread-safe - all the hard work is done by the >>>> operating system. >>>> >>>> [1] >>>> https://github.com/joyent/**libuv/commit/c5aa86b<https://github.com/joyent/libuv/commit/c5aa86b> >>>> >>> -- > Job Board: http://jobs.nodejs.org/ > Posting guidelines: > https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines > You received this message because you are subscribed to the Google > Groups "nodejs" group. > To post to this group, send email to [email protected] > To unsubscribe from this group, send email to > [email protected] > For more options, visit this group at > http://groups.google.com/group/nodejs?hl=en?hl=en > -- Job Board: http://jobs.nodejs.org/ Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines You received this message because you are subscribed to the Google Groups "nodejs" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/nodejs?hl=en?hl=en
