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 (smtp.nagaokaut.ac.jp [133.44.2.24]) by blade.nagaokaut.ac.jp (Postfix) with ESMTP id 5A5E41BA0009 for ; Mon, 8 May 2017 11:12:53 +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 EB465B5D877 for ; Mon, 8 May 2017 11:56:21 +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 5E95018D1D80 for ; Mon, 8 May 2017 11:56:22 +0900 (JST) Received: from neon.ruby-lang.org (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id EA41612072E; Mon, 8 May 2017 11:56:19 +0900 (JST) X-Original-To: ruby-core@ruby-lang.org Delivered-To: ruby-core@ruby-lang.org Received: from dcvr.yhbt.net (dcvr.yhbt.net [64.71.152.64]) by neon.ruby-lang.org (Postfix) with ESMTPS id 6FBCA12045C for ; Mon, 8 May 2017 11:56:16 +0900 (JST) Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id B326120188; Mon, 8 May 2017 02:56:14 +0000 (UTC) Date: Mon, 8 May 2017 02:56:14 +0000 From: Eric Wong To: ruby-core@ruby-lang.org Message-ID: <20170508025614.GA24763@starla> 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> <38090d10-c6a1-5097-66af-130275d773ea@atdot.net> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <38090d10-c6a1-5097-66af-130275d773ea@atdot.net> X-ML-Name: ruby-core X-Mail-Count: 81030 Subject: [ruby-core:81030] 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" SASADA Koichi wrote: > 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" OK. > > * 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. I think they should be usable as-is. Maybe users will want to manually switch after a certain time period. > * 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). I think it's important users continue to have options and be able to decide if blocking or non-blocking is better for their use case. > > * 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? Maybe some character devices/tty (I have never coded for them). There's no standard non-blocking I/O for regular files on POSIX. > > 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. Of course, I don't want to introduce too many new user-visible API. > > - 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? It might make it easier to port existing code and libraries written for Threads to use Fibers if something like Mutex can temporarily disable auto-switch. > > - IO#open, read-write I/O on filesystem release GVL as usual > > Not sure why they do. Non-blocking I/O is not possible on POSIX platforms. Existing AIO interfaces are always incomplete and inconsistent. We can try making our own AIO for File, but there will be more latency than current FS access with native threads. > > - It will be necessary to use resolv and resolv/replace in > > stdlib for Fiber-aware name resolution. > > It seems difficult... I'm not sure, I guess they become less-maintained nowadays since native threads came in 1.9 for getaddrinfo. But We can improve them. > > * 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). I don't think it will benefit to use per-thread epoll/kqueue, especially with GVL. epoll and kqueue have internal locking, anyways, so we can avoid adding our own locks around them. Sharing a single epoll/kqueue FD between dozens/hundreds of pthreads in cmogstored(*) is no problem at all (but cmogstored is designed for high-latency rotational disks). I believe GHC (Glasgow Haskell Compiler) uses a similar design based on one-shot epoll/kqueue notifications. > > 2. pipes and sockets get O_NONBLOCK flag set automatically > > when created inside Fibers with auto-scheduling set. > > not sure about it. Maybe there is compatibility problem when sharing FDs with other processes. But we had the reverse change from 1.8 -> 1.9, I think it is minor. (*) git clone git://bogomips.org/cmogstored All C99 + Ragel at runtime; only Ruby is in the test suite https://bogomips.org/cmogstored/queues.txt https://bogomips.org/cmogstored/design.txt