From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: poffice@blade.nagaokaut.ac.jp Delivered-To: poffice@blade.nagaokaut.ac.jp Received: from kankan.nagaokaut.ac.jp (kankan.nagaokaut.ac.jp [133.44.2.24]) by blade.nagaokaut.ac.jp (Postfix) with ESMTP id 706A81BA0009 for ; Mon, 8 May 2017 10:09:43 +0900 (JST) Received: from voscc.nagaokaut.ac.jp (voscc.nagaokaut.ac.jp [133.44.1.100]) by kankan.nagaokaut.ac.jp (Postfix) with ESMTP id A09C2B5D832 for ; Mon, 8 May 2017 10:53:11 +0900 (JST) Received: from neon.ruby-lang.org (neon.ruby-lang.org [221.186.184.75]) by voscc.nagaokaut.ac.jp (Postfix) with ESMTP id 0755B18CC80E for ; Mon, 8 May 2017 10:53:11 +0900 (JST) Received: from neon.ruby-lang.org (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id 7C0FB12069F; Mon, 8 May 2017 10:53:10 +0900 (JST) X-Original-To: ruby-core@ruby-lang.org Delivered-To: ruby-core@ruby-lang.org Received: from mail.atdot.net (ik1-326-23156.vs.sakura.ne.jp [153.126.180.160]) by neon.ruby-lang.org (Postfix) with ESMTP id B263B12045C for ; Mon, 8 May 2017 10:53:06 +0900 (JST) To: Ruby developers References: <20170402011414.AEA9B64CEE@svn.ruby-lang.org> <8a2b82e3-dc07-1945-55f9-5a474e89130b@ruby-lang.org> <20170402023514.GB30476@dcvr> <76459664-9857-4244-7d43-79b24e737efc@atdot.net> <20170403044254.GA16328@starla> <20170508003315.GA3789@starla> From: SASADA Koichi X-Enigmail-Draft-Status: N1110 Message-ID: <38090d10-c6a1-5097-66af-130275d773ea@atdot.net> Date: Mon, 8 May 2017 10:53:05 +0900 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 In-Reply-To: <20170508003315.GA3789@starla> X-ML-Name: ruby-core X-Mail-Count: 81028 Subject: [ruby-core:81028] Re: [ruby-cvs:65407] normal:r58236 (trunk): thread.c: comments on M:N threading [ci skip] X-BeenThere: ruby-core@ruby-lang.org X-Mailman-Version: 2.1.15 Precedence: list Reply-To: Ruby developers List-Id: Ruby developers List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ruby-core-bounces@ruby-lang.org Sender: "ruby-core" On 2017/05/08 9:33, Eric Wong wrote: > I have been thinking about this again; think M:N green Thread is > a bad idea[1]. Instead we should improve Fibers to make them > easier-to-use for cases where non-blocking I/O is _desirable_ > (not just _possible_). Great. That is exactly we are thinking. To discussion, let's define such auto-scheduling fibers "auto-fiber" > * not enabled by default for compatibility, maybe have: > Fiber.current.auto_schedule = (true|false) # per-fiber > Fiber.auto_schedule = (true|false) # process-wide > But I do not do Ruby API design :P Yes. I'm thinking to introduce new constructor like ScheduledFiber.new or something like that (maybe that name is not suitable, too). I believe we shouldn't change the behavior just after creation. BTW, we need to define the behavior of Fiber#resume, Fiber.yield and Fiber#transfer for auto-fibers. * Permit to use them. > * Existing native-thread code for blocking IO must (MUST!) > continue blocking w/o GVL as in current 2.4. > Users relying on blocking accept4() (via BasicSocket#accept) > still gets thundering herd protection when sharing listen > socket across multiple processes. > Ditto with UNIXSocket#recv_io when sharing a receiver socket. Not sure about this. We need to define I/O blocking operation again for this auto-switching fiber (maybe the following your documents define them). > * documented scheduling points: > > TL;DR: most existing "blocking" APIs become Fiber-aware, > similar to 1.8 green threads. > > - IO operations on pipe and sockets inside Fibers with > auto-scheduling enabled automatically become Fiber-aware > and use non-blocking internal interfaces while presenting > a synchronous API: Only pipe and sockets? > IO#read/write/syswrite/sysread/readpartial/gets etc.. > IO.copy_stream, IO.select > Socket#connect/accept/sysaccept > UNIXSocket#recv_io/#send_io > IO#wait_*able (in io/wait ext) > > - Ditto for some non-IO things: > > Kernel#sleep > Process.wait/waitpid/waitpid2 family uses WNOHANG > Queue/SizedQueue support, maybe new Fiber::Queue and > Fiber::SizedQueue classes needed? Just now, Fiber::Queue is not good idea I think because it is difficult to switch Thread::Queue and Fiber::Queue. However, I agree that we need to introduce scheduling primitives and Queue is good to use. We need to introduce it carefully. > - keep Mutex and ConditionVariable as-is for native Thread > user, I don't believe they are necessary for pure Fiber use. > Maybe add an option for Mutex locks to prevent Fiber.yield > and disable auto-scheduling temporarily? I can't understand that. Mutex (and so on) are for Threads. Does they need to care Fibers? > - IO#open, read-write I/O on filesystem release GVL as usual Not sure why they do. > - It will be necessary to use resolv and resolv/replace in > stdlib for Fiber-aware name resolution. It seems difficult... > * Implementation (steps can be done gradually): > > 1. new internal IO scheduler using kqueue/epoll/select. Native > kqueue/epoll allow cross-native-thread operation to share > the event loop, so they only need one new FD per-process. > I want to avoid libev/libevent since (last I checked) they > do not allow sharing an event loop across native threads. > I can write kqueue/epoll/select parts; I guess win32 can use > select until someone else implements something > > Maybe build IO scheduler into current timer thread.... I planned to run per-thread Fiber scheduler and to use epoll (and so on) on the thread because of overhead of cross-thread communication. I think we need to compare them (I didn't try it yet). > 2. pipes and sockets get O_NONBLOCK flag set automatically > when created inside Fibers with auto-scheduling set. not sure about it. > 3. rb_wait_single_fd can use new IO scheduler and becomes > Fiber-aware, ditto with rb_thread_fd_select... > > Steps 2 and 3 should make most IO changes transparent. > > 4. make necessary changes to Process.wait*, IO.select, > Kernel.sleep > > > > Side note: I consider making Fibers migratable across native > Threads out-of-scope for this. We currently use > makecontext/swapcontext (FIBER_USE_NATIVE) for speed (which > according to cont.c comments is significant). I am not > sure if we can keep FIBER_USE_NATIVE if allowing Fibers > to migrate across native threads. > > > [1] general problem with threads: > timeslice scheduling leads to unpredictability > like Mutex/ConditionVariables become necessary. > > M:N will be problematic, as it will be difficult for > users to know when it is safe to use heavy native threads > for blocking operations and when their threads will be > lightweight; making it difficult to design apps to use > each appropriately. > > However, native 1:1 Threads will always be useful for cases > where users can take advantage of blocking I/O > (#recv_io/#accept/File.open/...) as well as releasing GVL > for CPU-intensive operations independent of Ruby VM. > > Thanks for reading, I wrote most of this while waiting for > tests to r58604 to run before committing. > > Unsubscribe: > > -- // SASADA Koichi at atdot dot net