Discussion:
Green threads in 1.9.* ?
(too old to reply)
rex goxman
2012-07-04 10:57:18 UTC
Permalink
I am new to Ruby. I am somewhat surprised that I was not able to find
much info on this question via google or searching of forums. I was
able to find a similar question posted a while back but no one answered
it. Perhaps threads aren't such an important topic in Ruby culture?

Anyway, to the point. I'd like to use green threads (NOT kernel
threads) in a Ruby program I'm writing. There is no reason for me to
use kernel threads, and every reason to use green ones.

Are green threads still available? If so, how do I access/use them
(Thread class says nothing about whether it is green or kernel - I
suspect kernel)? If not, why not?

If not available, are there any alternatives? I checked into fibers,
but they are not appropriate for what I want because if an exception
happens, it happens in the "main thread" I am executing, which I don't
want.

Thanks.

--
Posted via http://www.ruby-forum.com/.
Jan E.
2012-07-04 11:19:10 UTC
Permalink
Hi,

As far as I understand, Ruby 1.9 has native threads, but they're blocked
by the Global Interpreter Lock.

So they should work like you want them to.

--
Posted via http://www.ruby-forum.com/.
Xavier Noria
2012-07-04 11:25:49 UTC
Permalink
It depends on the interpreter. This post may help you get the picture:

http://www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ruby/
rex goxman
2012-07-04 11:45:08 UTC
Permalink
@jacques1 and fxn above:

Are you saying that green threads are used regardless of what is
happening with kernel threads and the GIL? The thread posted by fxn
seems to indicate this.

Thanks.

--
Posted via http://www.ruby-forum.com/.
Jan E.
2012-07-04 11:52:38 UTC
Permalink
rex goxman wrote in post #1067385:
> Are you saying that green threads are used regardless of what is
> happening with kernel threads and the GIL? The link posted by fxn
> seems to indicate this.

This looks like a mistake. Ruby 1.8 has green threads, Ruby 1.9 and
JRuby have native threads (though Ruby 1.9 has a GIL).

--
Posted via http://www.ruby-forum.com/.
Xavier Noria
2012-07-04 12:11:10 UTC
Permalink
On Wed, Jul 4, 2012 at 1:45 PM, rex goxman <***@ruby-forum.com> wrote:

@jacques1 and fxn above:
>
> Are you saying that green threads are used regardless of what is
> happening with kernel threads and the GIL? The thread posted by fxn
> seems to indicate this.


I don't know enough to give a definitive answer (or plainly put, to
answer), but here's my interpretation of the post:

I believe the green threads in Ilya's post are the Ruby-land thread
objects, they are not necessarily green in the sense of who is doing the
scheduling. This is my interpretation a posteriori because of the way the
JVM is drawn.

They are definitely green threads in MRI 1.8 in the sense that MRI did
scheduling (you already know that).

Then, behind the scenes, they are mapped to native threads in MRI 1.9 and
JRuby. One-to-one. In the case of MRI there's a GIL. I guess technically a
GIL does not mean that MRI is doing the scheduling, it means MRI is holding
a lock, but the kernel schedules the native thread (because it is native).
Maybe there's a gray area in the definition of green thread here, I don't
know.

That is my interpretation, but I don't know enough to be certain. Please
someone correct me if that is wrong!
Tony Arcieri
2012-07-05 01:33:38 UTC
Permalink
On Wed, Jul 4, 2012 at 5:11 AM, Xavier Noria <***@hashref.com> wrote:

> Then, behind the scenes, they are mapped to native threads in MRI 1.9 and
> JRuby. One-to-one. In the case of MRI there's a GIL. I guess technically a
> GIL does not mean that MRI is doing the scheduling, it means MRI is holding
> a lock, but the kernel schedules the native thread (because it is native).
> Maybe there's a gray area in the definition of green thread here, I don't
> know.
>

MRI is still doing the scheduling in 1.9. It runs a timer thread that
interrupts running threads after a certain amount of time so waiting
threads can run. This way a single thread doing some computationally
intensive operation doesn't monopolize the entire VM.

--
Tony Arcieri
Eric Hodel
2012-07-05 20:22:38 UTC
Permalink
On Jul 4, 2012, at 18:33, Tony Arcieri wrote:
> On Wed, Jul 4, 2012 at 5:11 AM, Xavier Noria <***@hashref.com> wrote:
>> Then, behind the scenes, they are mapped to native threads in MRI 1.9 and JRuby. One-to-one. In the case of MRI there's a GIL. I guess technically a GIL does not mean that MRI is doing the scheduling, it means MRI is holding a lock, but the kernel schedules the native thread (because it is native). Maybe there's a gray area in the definition of green thread here, I don't know.
>
> MRI is still doing the scheduling in 1.9. It runs a timer thread that interrupts running threads after a certain amount of time so waiting threads can run. This way a single thread doing some computationally intensive operation doesn't monopolize the entire VM.

A more accurate picture of 1.9 is:

The OS schedules threads to run on CPUs.

The ruby VM has a global lock that only allows one thread to run ruby code at a time (the GVL). The GVL is also held for execution inside C extensions unless the author releases the GVL (most extensions release the GVL for some part of their operation).

Ruby schedules use of the GVL for threads created by the ruby VM.

A Ruby thread may release the GVL to run non-ruby code. An example would be performing a long calculation such as interacting with a DB, processing zlib streams, XML parsing with libxml2, etc. Such tasks don't need to communicate with the ruby VM so they can be running on separate CPUs at the same time as the ruby VM.

A Ruby thread will release the GVL when it performs a blocking operation such as IO or other system calls.

So the OS and the ruby VM cooperate on thread scheduling. If multiple ruby threads do not need the GVL to run the OS does the majority of the scheduling. If multiple ruby threads do need the GVL ruby does the majority of the scheduling.
Jos Backus
2012-07-05 20:35:31 UTC
Permalink
On Thu, Jul 5, 2012 at 1:22 PM, Eric Hodel <***@segment7.net> wrote:

> A more accurate picture of 1.9 is:
>
> The OS schedules threads to run on CPUs.
>
> The ruby VM has a global lock that only allows one thread to run ruby code
> at a time (the GVL). The GVL is also held for execution inside C
> extensions unless the author releases the GVL (most extensions release the
> GVL for some part of their operation).
>
> Ruby schedules use of the GVL for threads created by the ruby VM.
>
> A Ruby thread may release the GVL to run non-ruby code. An example would
> be performing a long calculation such as interacting with a DB, processing
> zlib streams, XML parsing with libxml2, etc. Such tasks don't need to
> communicate with the ruby VM so they can be running on separate CPUs at the
> same time as the ruby VM.
>
> A Ruby thread will release the GVL when it performs a blocking operation
> such as IO or other system calls.
>
> So the OS and the ruby VM cooperate on thread scheduling. If multiple
> ruby threads do not need the GVL to run the OS does the majority of the
> scheduling. If multiple ruby threads do need the GVL ruby does the
> majority of the scheduling.
>

This would make a good FAQ entry, I think. Thanks, Eric.

Jos
--
Jos Backus
jos at catnook.com
rex goxman
2012-07-05 21:22:19 UTC
Permalink
Eric Hodel wrote in post #1067586:
> Ruby schedules use of the GVL for threads created by the ruby VM.
>
> A Ruby thread may release the GVL to run non-ruby code.

What is a ruby thread? A green thread? A kernel thread? A green
thread mapped to a kernel thread?

The depiction at the link somewhere above seems to suggest it is a green
thread which is mapped one-to-one to a kernel thread. Some here suggest
there is no such thing, just kernel threads. I will assume it is a
kernel thread unless you say otherwise.

Eric Wong wrote...
> I know you don't like fibers, but the "neverblock" gem uses Fibers
> transparently under 1.9 to provide green threads. However, I'm
> not sure how active "neverblock" development is these days.

Actually I like fibers quite a bit, I just didn't think they were
applicable in this particular circumstance. I can check into neverblock
- thanks.

--
Posted via http://www.ruby-forum.com/.
Eric Hodel
2012-07-06 21:25:33 UTC
Permalink
On Jul 5, 2012, at 14:22, rex goxman wrote:
> Eric Hodel wrote in post #1067586:
>> Ruby schedules use of the GVL for threads created by the ruby VM.
>>
>> A Ruby thread may release the GVL to run non-ruby code.

For these answers I am ignoring Windows. You can probably treat "POSIX thread" as the equivalent userland threads on Windows, but don't take my word for it.

> What is a ruby thread?

A thread spawned from ruby. Non-ruby threads can be spawned by other libraries. For example, if you've embedded ruby in a game engine the game engine can have many of its own threads which ask ruby threads to do work.

> A green thread?

Any program that manages thread creation and scheduling for itself without use of the OS uses green threads.

> A kernel thread?

The most literal definition is a thread that runs in, and only in, the kernel. You can ignore them for most purposes since you don't have any direct control over when or how many are created by your process (this is true for all programs, not just ruby programs). I think that most frequently, kernel threads are mapped 1:1 to userland threads, but this may vary between different OSs.

At one point FreeBSD had multiple pthread implementations you could link in your program. One had 1:1 mapping between kernel threads and userland threads, one had 1:N mapping (one kernel thread per process) and one M:N mapping (multiple userland threads per kernel thread).

Userland threads are what userland programs run. The POSIX thread API (pthread) handles userland threads and takes care of spawning the threads, allocating stack space for them, etc. Depending upon the mapping to kernel threads they may be scheduled from userland or from the kernel. (I think, most frequently, from the kernel.)

> A green thread mapped to a kernel thread?

Since a green thread is scheduled from within a program the kernel has no knowledge of it so they won't be mapped.

> The depiction at the link somewhere above seems to suggest it is a green
> thread which is mapped one-to-one to a kernel thread.

Since pthreads typically make some communication with the kernel it isn't correct to call them green threads. It's possible to have a pthread library that makes no communication with the kernel (a library similar to FreeBSD's 1:N thread library could do this), but in practice I doubt this happens. It's difficult for a thread library to schedule a process' threads on multiple CPUs without some communication with the kernel.

> Some here suggest there is no such thing, just kernel threads. I will assume it is a kernel thread unless you say otherwise.

I think what they describe as "kernel threads" I call "userland threads". The OS often has its own threads to perform OS tasks such as userland scheduling, handling interrupts, polling for IO from hardware, etc. I don't wish to confuse the two.

Digging in further to thread.c, the GVL is not directly part of userland thread scheduling or ruby thread scheduling, it's just a lock around the ruby VM that allows a thread to use the ruby VM. (If a thread calls methods in the Ruby VM without the GVL it will likely cause corruption and crashes.) Ruby uses pthread API to switch threads so it's up to the OS which threads get run.

Ruby will interrupt threads that have run for "too long" and allow the OS to schedule another thread. This is all performed through pthread mutexes and condition variables. (Perhaps I'm missing it, but I'm no longer seeing a list of threads waiting to run as I recall 1.8 having which is a requirement for a green thread implementation.)
rex goxman
2012-07-04 12:26:32 UTC
Permalink
If jacques1 is right, then there are no green threads, just kernel
threads, and I'm out of luck (anyone know why they would do away with
green threads instead of keeping them and also adding kernel threads?).

I did a quick-and-dirty test here (ruby 1.9.3) to try to shed some
light. My assumption is that green threads should be incredibly cheap
to create (on the order of at least thousands per second), where as
kernel threads should be much, much slower.

(1..5000).each {Thread.new{}}

This takes around 12 seconds to execute on my machine. It seems far too
slow for green threads (I can create hundreds of thousands of green
processes in erlang per second). However, someone out there correct me
if I am wrong, but I would also expect kernel threads to be much slower
than the above, i.e. on the order of a few per second. I coded up a TCL
version of the same above, which I know uses kernel threads. It only
spawned a couple heavyweights per second.

I guess the results are indeterminate? Hopefully someone else will
chime in who knows definitively.

--
Posted via http://www.ruby-forum.com/.
Peter Zotov
2012-07-04 12:30:09 UTC
Permalink
rex goxman писал 04.07.2012 16:26:
> If jacques1 is right, then there are no green threads, just kernel
> threads, and I'm out of luck (anyone know why they would do away with
> green threads instead of keeping them and also adding kernel
> threads?).
>
> I did a quick-and-dirty test here (ruby 1.9.3) to try to shed some
> light. My assumption is that green threads should be incredibly
> cheap
> to create (on the order of at least thousands per second), where as
> kernel threads should be much, much slower.
>
> (1..5000).each {Thread.new{}}
>
> This takes around 12 seconds to execute on my machine. It seems far
> too
> slow for green threads (I can create hundreds of thousands of green
> processes in erlang per second). However, someone out there correct
> me
> if I am wrong, but I would also expect kernel threads to be much
> slower
> than the above, i.e. on the order of a few per second. I coded up a
> TCL
> version of the same above, which I know uses kernel threads. It only
> spawned a couple heavyweights per second.
>
> I guess the results are indeterminate? Hopefully someone else will
> chime in who knows definitively.

Ruby 1.9 uses kernel threads and does not have green threads.
There is nothing like Erlang's lightweight processes in Ruby (or, for
that matter, in most of the languages).

--
WBR, Peter Zotov.
Xavier Noria
2012-07-04 12:41:08 UTC
Permalink
On Wed, Jul 4, 2012 at 2:30 PM, Peter Zotov <***@whitequark.org>wrote:

Ruby 1.9 uses kernel threads and does not have green threads.
> There is nothing like Erlang's lightweight processes in Ruby (or, for
> that matter, in most of the languages).


That is clear, but the definition of green thread depends on who schedules
them.

Is the GIL acting as a scheduler? Has MRI logic about what to lock next
therefore scheduling in practice *among the threads in its process*? Or is
my conjecture right that locking is mostly dumb and that ultimately the
kernel is the scheduler because the thread is native?
Peter Zotov
2012-07-04 12:45:14 UTC
Permalink
Xavier Noria писал 04.07.2012 16:41:
> On Wed, Jul 4, 2012 at 2:30 PM, Peter Zotov
> <***@whitequark.org>wrote:
>
> Ruby 1.9 uses kernel threads and does not have green threads.
>> There is nothing like Erlang's lightweight processes in Ruby (or,
>> for
>> that matter, in most of the languages).
>
>
> That is clear, but the definition of green thread depends on who
> schedules
> them.
>
> Is the GIL acting as a scheduler? Has MRI logic about what to lock
> next
> therefore scheduling in practice *among the threads in its process*?
> Or is
> my conjecture right that locking is mostly dumb and that ultimately
> the
> kernel is the scheduler because the thread is native?

The OP's problem is not the scheduler itself but the associated system
resources.
You can create 20k Erlang processes ("threads"). You cannot create 20k
pthreads. Just that.

--
WBR, Peter Zotov.
Xavier Noria
2012-07-04 12:59:38 UTC
Permalink
On Wed, Jul 4, 2012 at 2:45 PM, Peter Zotov <***@whitequark.org>wrote:

Xavier Noria пОсал 04.07.2012 16:41:
>
> On Wed, Jul 4, 2012 at 2:30 PM, Peter Zotov <***@whitequark.org>**
>> wrote:
>>
>> Ruby 1.9 uses kernel threads and does not have green threads.
>>
>>> There is nothing like Erlang's lightweight processes in Ruby (or, for
>>> that matter, in most of the languages).
>>>
>>
>>
>> That is clear, but the definition of green thread depends on who schedules
>> them.
>>
>> Is the GIL acting as a scheduler? Has MRI logic about what to lock next
>> therefore scheduling in practice *among the threads in its process*? Or is
>> my conjecture right that locking is mostly dumb and that ultimately the
>> kernel is the scheduler because the thread is native?
>>
>
> The OP's problem is not the scheduler itself but the associated system
> resources.
> You can create 20k Erlang processes ("threads"). You cannot create 20k
> pthreads. Just that.


Looks so also to me, but Ilya's post makes that clear (and it is a known
characteristic of MRI 1.9)... why the followup then after I linked to the
post?
rex goxman
2012-07-04 16:13:32 UTC
Permalink
Peter Zotov wrote in post #1067393:
> There is nothing like Erlang's lightweight processes in Ruby (or, for
> that matter, in most of the languages).

Well, for the purposes here, if Ruby's threads were green threads, yes
they would have been comparable to Erlang green processes. My emphasis
is far more on the "green" and far less on whether it is a process or a
thread.

As far as the definition of green and whether it has anything to do with
a scheduler or not, my definition of green is simply whether or not it
is a 'real' thread or simply a virtual thread which lives inside of the
vm.

--
Posted via http://www.ruby-forum.com/.
Jan E.
2012-07-04 16:24:05 UTC
Permalink
rex goxman wrote in post #1067433:
> Well, for the purposes here, if Ruby's threads were green threads, yes
> they would have been comparable to Erlang green processes. My emphasis
> is far more on the "green" and far less on whether it is a process or a
> thread.

Ruby 1.8 *has* green threads. It's explained in Xavier's link, and I
also mentioned it above.

You seem to misread "some implementations have native threads" as "all
have native threads".

--
Posted via http://www.ruby-forum.com/.
rex goxman
2012-07-04 17:03:14 UTC
Permalink
Jan E. wrote in post #1067435:
> rex goxman wrote in post #1067433:
>> Well, for the purposes here, if Ruby's threads were green threads, yes
>> they would have been comparable to Erlang green processes. My emphasis
>> is far more on the "green" and far less on whether it is a process or a
>> thread.
>
> Ruby 1.8 *has* green threads. It's explained in Xavier's link, and I
> also mentioned it above.
>
> You seem to misread "some implementations have native threads" as "all
> have native threads".

The title of this post is "green threads in 1.9.* ?" Furthermore, I
have this edit in one of my posts here:

> EDIT: 1.9.x of course.

So I have misread nothing. I am **ONLY** talking about 1.9.*. I could
care less about 1.8 or any other implementation.

Thanks.

--
Posted via http://www.ruby-forum.com/.
Matthew Kerwin
2012-07-04 23:39:50 UTC
Permalink
On 5 July 2012 03:03, rex goxman <***@ruby-forum.com> wrote:
> So I have misread nothing. I am **ONLY** talking about 1.9.*. I could
> care less about 1.8 or any other implementation.

Couldn't. Unless your level of caring is greater than your minimum. Or
you can have negative carativitiy.

I'm pretty sure Xavier (fxn) has answered this thread pretty well. My
question is: do you really care about the greenness of the threads
(academically), or do you actually want to know how best to utilise
them since they seem to have unusual profiling characteristics?

If the former, I don't know what to suggest. Research, code scouring,
reverse engineering (or read the link posted earlier). If the latter,
I say explore and research, and if you find something that works best
for your application use it, and maybe share it with us in case we
need to do it again some day.

As an aside, and I'm not pointing the finger at anyone in this thread
when I say this, but a week or two ago I commented to a colleague of
mine about how polite the ruby-talk forum was, and how people seemed
to consciously avoid flaming and trolling, and how noobs got useful
help even when they asked "dumb noob" questions, and how people said
"thank you" . . . but in the past couple of days there've been a few
discussions (usually related to optimisation or performance) that have
developed a very negative tone, if not outright ALL CAPS TYPING and
rage. What's going on? I want a return to the happy, friendly
ruby-talk of yesterweek.

--
Matthew Kerwin, B.Sc (CompSci) (Hons)
http://matthew.kerwin.net.au/
ABN: 59-013-727-651

"You'll never find a programming language that frees
you from the burden of clarifying your ideas." - xkcd
Alex Chaffee
2012-07-06 16:31:34 UTC
Permalink
> I want a return to the happy, friendly ruby-talk of yesterweek.

One small step would be to stop (gently) mocking people for using
well-accepted variants of colloquial idioms. :-)

>> I could care less about 1.8 or any other implementation.
>
> Couldn't. Unless your level of caring is greater than your minimum. Or you can have negative carativitiy.

http://articles.boston.com/2010-10-24/lifestyle/29303907_1_care-peeves-decades
http://itre.cis.upenn.edu/~myl/languagelog/archives/001182.html

TL;DR: "I could care less" is at least 50 years old, and can be
explained as sarcasm, hyperbole, and/or a long-ago confusion now lost
in history (like "una narancia" became "a norange" became "an orange")
-- not as evidence of the speaker's idiocy.

That said, rex was being pretty defensive and peevish. Group hug!

--
Alex Chaffee - ***@stinky.com
http://alexchaffee.com
http://twitter.com/alexch
Mark Abramov
2012-07-04 14:57:02 UTC
Permalink
You could try to emulate green threads using a native thread pool +
fibers.

--
Posted via http://www.ruby-forum.com/.
Mark Abramov
2012-07-04 15:19:39 UTC
Permalink
You might also want to look into tarcieri's celluloid:
https://github.com/celluloid/celluloid/

--
Posted via http://www.ruby-forum.com/.
Tony Arcieri
2012-07-05 01:30:31 UTC
Permalink
On Wed, Jul 4, 2012 at 3:57 AM, rex goxman <***@ruby-forum.com> wrote:

> I'd like to use green threads (NOT kernel threads) in a Ruby program I'm
> writing. There is no reason for me to
> use kernel threads, and every reason to use green ones.
>

If you want to use 1.9, you're out of luck. That said, you aren't stating
your reasoning for why you would prefer green threads over native ones.

Native threads have a longer creation time and use marginally more memory
(they use ~20kB per thread last I measured), however they generally perform
better, particularly around I/O. On platforms like Linux scheduling is O(1)
so there's really no reason you can't create large numbers of threads.

There are definitely many reasons to prefer native threads over green
threads. This is the reason why you have seen a shift from green threads to
native threads in MRI, Rubinius, and the JVM.

Why do you want green threads?

--
Tony Arcieri
rex goxman
2012-07-05 13:38:31 UTC
Permalink
<<There are definitely many reasons to prefer native threads over green
threads. This is the reason why you have seen a shift from green threads
to
native threads in MRI, Rubinius, and the JVM.

Why do you want green threads?>>

There are many situations to prefer green threads over kernel
threads. It's why I'm somewhat surprised that Ruby is just ditching
green threads, vs. keeping them and deploying kernel threads along side
them. Perhaps it's a cultural thing. Rubyists might be more concerned
with things like web servers (Rails development) and what not, and
perhaps haven't found want or need for green threads so much (just a
guess).

One reason to prefer green threads is if your application doesn't need
speed up through concurrency/parallelism, rather you want a threaded
solution for algorithmic purposes, convenience purposes, or other
purposes. This is a crappy example, but say you need to do some
calculation which might fail or even crash, but you don't want (or need)
to check the inputs to the calculation, or wrap the thing up in an error
catching mechanism, or anything of this nature. You just want to
calculate it, and if it works, fine, and if it doesn't (or even crashes)
- fine, your main program continues to run. So spawn a green thread to
run the calculation. If it works, great. If it crashes, who cares?

You might say "do that with a kernel thread." But what if I want to
spawn this thread over and over again in a tight loop? I don't want or
need the monstrous overhead of a kernel thread here. I just want a
green thread.

Again, there's a whole host of situations where one might want to have
green threads vs. kernel threads. But I wasn't here to debate that - if
Rubyists want to throw green threads in the garbage, that's their
prerogative. I was just here to ask whether there were green threads or
not (in 1.9.*).

--
Posted via http://www.ruby-forum.com/.
Tony Arcieri
2012-07-05 16:34:13 UTC
Permalink
On Thu, Jul 5, 2012 at 6:38 AM, rex goxman <***@ruby-forum.com> wrote:

> This is a crappy example, but say you need to do some
> calculation which might fail or even crash, but you don't want (or need)
> to check the inputs to the calculation, or wrap the thing up in an error
> catching mechanism, or anything of this nature. You just want to
> calculate it, and if it works, fine, and if it doesn't (or even crashes)
> - fine, your main program continues to run. So spawn a green thread to
> run the calculation. If it works, great. If it crashes, who cares?
>

You want threads as a way to silently swallow exceptions? o_O I'm going to
go out on a limb and say that's a terrible application for threads...

You might say "do that with a kernel thread." But what if I want to
> spawn this thread over and over again in a tight loop? I don't want or
> need the monstrous overhead of a kernel thread here. I just want a
> green thread.
>

If the time it takes to spawn a thread is really too much, use a thread
pool.

--
Tony Arcieri
Florian Gilcher
2012-07-05 16:45:13 UTC
Permalink
Am 05.07.2012 um 18:34 schrieb Tony Arcieri <***@gmail.com>:

> On Thu, Jul 5, 2012 at 6:38 AM, rex goxman <***@ruby-forum.com> wrote:
>>
>> You might say "do that with a kernel thread." But what if I want to
>> spawn this thread over and over again in a tight loop? I don't want or
>> need the monstrous overhead of a kernel thread here. I just want a
>> green thread.
>
> If the time it takes to spawn a thread is really too much, use a thread pool.

Couldn't a similar design be achieved by using Fibers and a Thread pool that grabs work from a list of ready Fibers?
Tony Arcieri
2012-07-05 16:53:52 UTC
Permalink
On Thu, Jul 5, 2012 at 9:45 AM, Florian Gilcher <***@andersground.net>wrote:

> Couldn't a similar design be achieved by using Fibers and a Thread pool
> that grabs work from a list of ready Fibers?
>

Fibers are pinned to the threads they are created in and cannot be resumed
in other threads

--
Tony Arcieri
rex goxman
2012-07-05 17:26:37 UTC
Permalink
Tony Arcieri wrote in post #1067551:
> You want threads as a way to silently swallow exceptions? o_O I'm going
> to
> go out on a limb and say that's a terrible application for threads...

1. Tell that to Erlangers.

2. I did preface that with

>> This is a crappy example, but ...

In short, no, that's not really my application for them, just know that
I have one.

> If the time it takes to spawn a thread is really too much, use a thread
> pool.

You seem to be of the mindset that there couldn't possibly be any reason
or circumstance to want to use green threads. Okay, "whatever" I guess.

--
Posted via http://www.ruby-forum.com/.
Tony Arcieri
2012-07-05 17:38:46 UTC
Permalink
On Thu, Jul 5, 2012 at 10:26 AM, rex goxman <***@ruby-forum.com> wrote:

> 1. Tell that to Erlangers.
>

I assure you, I am quite familiar with Erlang:
https://github.com/tarcieri/reia

Whenever an OTP process (e.g. gen_server, gen_event) crashes, the reason
for the crash is meticulously logged by the OTP logging framework. This is
pretty much the only way to debug asynchronous behaviors, as if the
exceptions are swallowed by default you have no outward indication of what
happened.

Erlang provides a great example of a system that is the exact opposite of
the one you are proposing.

--
Tony Arcieri
rex goxman
2012-07-05 19:31:00 UTC
Permalink
Tony Arcieri wrote in post #1067563:
> Erlang provides a great example of a system that is the exact opposite
> of
> the one you are proposing.

1. I have proposed no system. I have stated that I'd like to use green
threads, and asked if ruby still had them available.

2. Erlang uses green processes, emphasis on 'green'.

--
Posted via http://www.ruby-forum.com/.
Tony Arcieri
2012-07-06 00:37:39 UTC
Permalink
On Thu, Jul 5, 2012 at 12:31 PM, rex goxman <***@ruby-forum.com> wrote:

> 1. I have proposed no system. I have stated that I'd like to use green
> threads, and asked if ruby still had them available.


Your suggested use case for green threads was firing off background jobs
that may or may not break, with zero interest as to if they complete
successfully. This is not what Erlang does. Erlang/OTP provides extensive
reporting of all failures of any OTP components.

At least, that seems to be what you're suggesting here. Please correct me
if I'm wrong:

This is a crappy example, but say you need to do some
> calculation which might fail or even crash, but you don't want (or need)
> to check the inputs to the calculation, or wrap the thing up in an error
> catching mechanism, or anything of this nature. You just want to
> calculate it, and if it works, fine, and if it doesn't (or even crashes)
> - fine, your main program continues to run.


--
Tony Arcieri
Tony Arcieri
2012-07-06 01:12:08 UTC
Permalink
I'd also like to reiterate that Erlang is doing the right thing here and
that silently swallowing errors in an asynchronous concurrent system (which
is what you're proposing) is an extremely bad idea. In an asynchronous
system, the error log is your only tool for understanding what's broken and
where. You will most certainly want to capture and log all errors, not
silently ignore them, or else you will have no visibility into if your
asynchronous background tasks are working or not.

On Thu, Jul 5, 2012 at 5:37 PM, Tony Arcieri <***@gmail.com> wrote:

> On Thu, Jul 5, 2012 at 12:31 PM, rex goxman <***@ruby-forum.com> wrote:
>
>> 1. I have proposed no system. I have stated that I'd like to use green
>> threads, and asked if ruby still had them available.
>
>
> Your suggested use case for green threads was firing off background jobs
> that may or may not break, with zero interest as to if they complete
> successfully. This is not what Erlang does. Erlang/OTP provides extensive
> reporting of all failures of any OTP components.
>
> At least, that seems to be what you're suggesting here. Please correct me
> if I'm wrong:
>
> This is a crappy example, but say you need to do some
>> calculation which might fail or even crash, but you don't want (or need)
>> to check the inputs to the calculation, or wrap the thing up in an error
>> catching mechanism, or anything of this nature. You just want to
>> calculate it, and if it works, fine, and if it doesn't (or even crashes)
>> - fine, your main program continues to run.
>
>
> --
> Tony Arcieri
>
>


--
Tony Arcieri
rex goxman
2012-07-06 03:32:15 UTC
Permalink
Tony Arcieri wrote in post #1067610:
> I'd also like to reiterate that Erlang is doing the right thing here and
> that silently swallowing errors in an asynchronous concurrent system
> (which
> is what you're proposing) is an extremely bad idea.

If you are saying that there never has been nor never will be a use case
for anyone on the planet where they might want to silently swallow
errors in an asynchronous concurrent system, and that to even
contemplate such is always a bad idea, then you, sir, are an idiot.

--
Posted via http://www.ruby-forum.com/.
rex goxman
2012-07-06 03:24:41 UTC
Permalink
Tony Arcieri wrote in post #1067609:
> Your suggested use case for green threads was firing off background jobs
> that may or may not break, with zero interest as to if they complete
> successfully.

I'm not sure if you are someone with reading-comprehension issues, or a
troll. I will state (again) that I threw a "crappy" example out there
off the top of my head as a reason someone might want green threads. I
did this because some people seem to lack the creativity to come up with
use cases themselves, which are plentiful and abound. In hindsight, it
seems to have been a serious mistake on my part to have done this, since
you continue to ignore the fact that I stated it was a "crappy" example
and continue to inexplicably seize upon what I wrote as some opportunity
to "hammer" me.

Having said that, I stand by what I said. You might want to fire off
background jobs that may or may not break, with zero interest as to if
they complete successfully.

> This is not what Erlang does. Erlang/OTP provides
> extensive
> reporting of all failures of any OTP components.

Erlang "does" whatever you want it to do, bro. If you want process
supervision, extensive reporting of all failures, blah blah, it is
there. If you don't want that (and in many cases, you don't), you don't
have to use it. As with anything, it depends on your application and
what you want to do with it.

--
Posted via http://www.ruby-forum.com/.
Tony Arcieri
2012-07-06 03:55:07 UTC
Permalink
On Thu, Jul 5, 2012 at 8:24 PM, rex goxman <***@ruby-forum.com> wrote:

> I'm not sure if you are someone with reading-comprehension issues, or a
> troll. I will state (again) that I threw a "crappy" example out there
> off the top of my head as a reason someone might want green threads. I
> did this because some people seem to lack the creativity to come up with
> use cases themselves, which are plentiful and abound. In hindsight, it
> seems to have been a serious mistake on my part to have done this, since
> you continue to ignore the fact that I stated it was a "crappy" example
> and continue to inexplicably seize upon what I wrote as some opportunity
> to "hammer" me.


So in other words, you don't have a use case for green threads

--
Tony Arcieri
Ryan Davis
2012-07-06 06:52:25 UTC
Permalink
On Jul 5, 2012, at 20:55 , Tony Arcieri wrote:

> On Thu, Jul 5, 2012 at 8:24 PM, rex goxman <***@ruby-forum.com> wrote:
> I'm not sure if you are someone with reading-comprehension issues, or a
> troll. I will state (again) that I threw a "crappy" example out there
> off the top of my head as a reason someone might want green threads. I
> did this because some people seem to lack the creativity to come up with
> use cases themselves, which are plentiful and abound. In hindsight, it
> seems to have been a serious mistake on my part to have done this, since
> you continue to ignore the fact that I stated it was a "crappy" example
> and continue to inexplicably seize upon what I wrote as some opportunity
> to "hammer" me.
>
> So in other words, you don't have a use case for green threads

Do you HAVE to have the last word? Is that what this is?

There are plenty of use cases for green threads, and YOU know that. The fact that Rex is not telling you his means nothing. Stop being a jackass.
Robert Klemme
2012-07-06 11:11:07 UTC
Permalink
On Fri, Jul 6, 2012 at 8:52 AM, Ryan Davis <ryand-***@zenspider.com> wrote:
>
> On Jul 5, 2012, at 20:55 , Tony Arcieri wrote:
>
>> On Thu, Jul 5, 2012 at 8:24 PM, rex goxman <***@ruby-forum.com> wrote:
>> I'm not sure if you are someone with reading-comprehension issues, or a
>> troll. I will state (again) that I threw a "crappy" example out there
>> off the top of my head as a reason someone might want green threads. I
>> did this because some people seem to lack the creativity to come up with
>> use cases themselves, which are plentiful and abound. In hindsight, it
>> seems to have been a serious mistake on my part to have done this, since
>> you continue to ignore the fact that I stated it was a "crappy" example
>> and continue to inexplicably seize upon what I wrote as some opportunity
>> to "hammer" me.
>>
>> So in other words, you don't have a use case for green threads
>
> Do you HAVE to have the last word? Is that what this is?

I think the point is, that as long as we do not know rex's real use
case we cannot come up with proper suggestions for alternative
solutions to green threads. So far rex provides a solution he wants
to use but I cannot really see the reasoning behind it.

Btw. even green threads come at a price and firing off a lot of tasks
by just creating threads (whatever color) when the task appears is not
likely going to work out well for large numbers of concurrent tasks.
In this case one would need some form of thread pool with a queue
anyway. And then the difference between green and kernel thread
creation is irrelevant anyway.

> There are plenty of use cases for green threads, and YOU know that. The fact that Rex is not telling you his means nothing. Stop being a jackass.

Actually I have doubts that there are so many use cases for green
threads. Off the top of my head only platforms which do not support
kernel threads come to mind. I'd love to hear more and especially the
case rex has in mind.

Other than that the overhead in terms of memory and CPU for creating a
kernel thread isn't too big nowadays. And from a global perspective
which covers operating system as well as hardware trends Matz's
decision to go for kernel threads is wise because that will eventually
give us better performance (once GIL is gone).

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
rex goxman
2012-07-06 12:40:43 UTC
Permalink
Robert Klemme wrote in post #1067663:
> So far rex provides a solution he wants
> to use but I cannot really see the reasoning behind it.

*Sigh*. I did not provide a "solution I want to use." I provided a
CRAPPY EXAMPLE off the top of my head that was advertised as a CRAPPY
EXAMPLE before giving the CRAPPY EXAMPLE.

I do not intend to divulge any real use cases for green threads because
they are intuitively obvious, apparent, easy to find or dream up for
one's self, and the literature is abundant and easily available. It's
sort of like being asked to give a use case for a hammer. I'm not here
to educate. If people want education, it's up to them to get it, not up
to me to provide it.

Use cases for green threads aren't controversial, and there is no debate
on it anywhere that I'm aware of... except perhaps here I guess. I
don't intend to debate whether or not green threads can be a good thing
and whether there are many use cases for them any more than I wish to
debate whether 2 + 2 = 4.

Now, whether Ruby wants to deploy and maintain a green threads solution
or not is another issue entirely, completely separate from the issue of
whether "green threads are good," or "green threads have many valid use
cases." The answers to the latter two issues are an unequivocal 'yes.'
The answer to the former could be anything, and rightly or wrongly so.

Ruby might have good reasons or not so good reasons for wanting or not
wanting to maintain green threads. I don't care, and I'm not here to
comment on that either way. While I did say I was somewhat surprised
that Ruby would ditch green threads altogether vs. keeping them around
and deploying kernel threads alongside, there may very well be good
reasons for such a decision, not least of which may simply be limited
resources to devote to a threading implementation, and thus a need to
simply pick one and go with it (just a guess).

> And from a global perspective
> which covers operating system as well as hardware trends Matz's
> decision to go for kernel threads is wise because that will eventually
> give us better performance (once GIL is gone).

Perhaps I have a clue here as to some of the... "interesting" responses
I have received on this. Perhaps it's a classic case of an "outsider"
being perceived as coming into a community and criticizing the leader of
the community.

If so, let me be clear. I have said nothing regarding Matz, nor of his
decision to go for kernel threads, nor the wisdom of that decision.
Whether green threads are "good" or not, and whether Matz made a wise
decision in ditching them for kernel threads, is two separate issues.
In other words, it is possible that "green threads are good" and "Matz
made a great decision and is a genius" are both true.

--
Posted via http://www.ruby-forum.com/.
Jam
2012-07-06 12:59:46 UTC
Permalink
On Jul 6, 2012, at 6:40 AM, rex goxman <***@ruby-forum.com> wrote:

> Robert Klemme wrote in post #1067663:
>> So far rex provides a solution he wants
>> to use but I cannot really see the reasoning behind it.
>
> *Sigh*. I did not provide a "solution I want to use." I provided a
> CRAPPY EXAMPLE off the top of my head that was advertised as a CRAPPY
> EXAMPLE before giving the CRAPPY EXAMPLE.
>
>

Hey Rex,

I think you misunderstood here. You said you wanted to use green threads as a solution but haven't stated a problem i.e. you stated the solution you want.

I think there's a couple of different voices in this thread, but one recurring one is asking for your use case so that they can help come up with an alternate solution. It doesn't sound like you are looking for an alternate, though, just that you're surprised green threads were removed entirely.


Jams
William Paulson
2012-07-06 13:59:33 UTC
Permalink
"Green? I think perhaps this word does not mean what you think it means."

Perhaps this discussion would proceed more smoothly if we defined what's meant by a "green" thread, or avoided the term. Ruby programmers usually use the term "green threads" to mean implementations of Ruby's Thread class where the scheduling doesn't use OS support. These threads are otherwise middle-weight, akin to a Linux pthread. The expected use-case for Ruby Thread objects would usually have only a smallish number of objects, often approximating the number of cores in a server. For this sort of model, moving to an OS supported thread means that multicore parallelism is easier to achieve.

Rex, it sounds like the "green" threads you are thinking of may be a flyweight sort of object, where a program might have hundreds or thousands of entities. Threads of this type aren't usually supported by OS, so each language or application may support them, or not. Ruby Thread instances don't map well to this usage, independent of whether they use a "green" internal scheduler or external OS scheduler.

Sent from my iPhone

On Jul 6, 2012, at 7:59 AM, Jam <***@jamandbees.net> wrote:

>
>
> On Jul 6, 2012, at 6:40 AM, rex goxman <***@ruby-forum.com> wrote:
>
>> Robert Klemme wrote in post #1067663:
>>> So far rex provides a solution he wants
>>> to use but I cannot really see the reasoning behind it.
>>
>> *Sigh*. I did not provide a "solution I want to use." I provided a
>> CRAPPY EXAMPLE off the top of my head that was advertised as a CRAPPY
>> EXAMPLE before giving the CRAPPY EXAMPLE.
>>
>>
>
> Hey Rex,
>
> I think you misunderstood here. You said you wanted to use green threads as a solution but haven't stated a problem i.e. you stated the solution you want.
>
> I think there's a couple of different voices in this thread, but one recurring one is asking for your use case so that they can help come up with an alternate solution. It doesn't sound like you are looking for an alternate, though, just that you're surprised green threads were removed entirely.
>
>
> Jams
>
>
>
rex goxman
2012-07-06 15:12:10 UTC
Permalink
Bill Paulson wrote in post #1067690:
> Ruby programmers usually
> use the term "green threads" to mean implementations of Ruby's Thread
> class where the scheduling doesn't use OS support. These threads are
> otherwise middle-weight, akin to a Linux pthread. The expected use-case
> for Ruby Thread objects would usually have only a smallish number of
> objects, often approximating the number of cores in a server. For this
> sort of model, moving to an OS supported thread means that multicore
> parallelism is easier to achieve.
>
> Rex, it sounds like the "green" threads you are thinking of may be a
> flyweight sort of object, where a program might have hundreds or
> thousands of entities.

Very helpful. Indeed, the green threads I was thinking of were a
virtual flyweight sort of object similar to what I've used in other
systems. I wasn't aware that there were different usages of the term.

Thanks for the Rubyist usage of the term, and the clarification. I'm
willing to call the discussion closed and move on.

Regards.

--
Posted via http://www.ruby-forum.com/.
Tony Arcieri
2012-07-06 16:23:49 UTC
Permalink
On Fri, Jul 6, 2012 at 5:40 AM, rex goxman <***@ruby-forum.com> wrote:

> Use cases for green threads aren't controversial, and there is no debate

on it anywhere that I'm aware of... except perhaps here I guess.


You're right, there is no debate! Pretty much all major virtual machines
have moved from green threads to native threads. There are still systems
that offer M:N userspace "microthreads" to N native thread schedulers, such
as Erlang and Go, but these are different from green threaded systems which
eschew use of native threads entirely and attempt to emulate them entirely
in userspace.

On Thu, Jul 5, 2012 at 11:52 PM, Ryan Davis <ryand-***@zenspider.com>
wrote:

> Do you HAVE to have the last word? Is that what this is?
>
> There are plenty of use cases for green threads, and YOU know that. The
> fact that Rex is not telling you his means nothing. Stop being a jackass.
>

Actually, I really do believe that green threads are an antiquated concept
whose time has passed. Problems with thread creation time can be mitigated
using thread pools, and systems like Disruptor show you can have extremely
low-latency cross-thread communication with native threads, even when
there's contention around data structures, by doing the majority of your
synchronization in userspace.

--
Tony Arcieri
rex goxman
2012-07-07 07:57:33 UTC
Permalink
Tony Arcieri wrote in post #1067715:
> You're right, there is no debate! Pretty much all major virtual machines
> have moved from green threads to native threads.

Perhaps it depends on the definition of what is "major." I won't get
into that, everybody has their own definition I guess. But all
Smalltalk VMs I am aware of still use green threads. Smalltalk VM is
state of the art and has been developed for decades, so I don't see how
it couldn't be considered "major."

>From Cincom website:

http://www.cincomsmalltalk.com/userblogs/cincom/blogView?content=what_can_smalltalk_do

"A single Smalltalk process (image) runs in the context of one operating
system process, using a single OS level thread. Within that process, you
can manage an arbitrary number of lightweight (green) threads..."

I have used green threads on Haskell (GHC). Unless something has
changed, it still has them. It also has other threading models, but I
don't believe they removed green threads in order to have the other
threading models.

Erlang processes are still green.

> There are still systems
> that offer M:N userspace "microthreads" to N native thread schedulers,
> such
> as Erlang and Go, but these are different from green threaded systems
> which
> eschew use of native threads entirely and attempt to emulate them
> entirely
> in userspace.

Erlang processes are entirely "green," in the same way that a green
thread is "green." Yes, nowadays they can be mapped to 'real' threads
running on multiple cores, and that's a good thing. But they are still
green. My crappy notebook can spawn in the hundreds of thousands a
second. Each one takes up a ridiculously small amount of memory. I can
have millions of the things running in just a few lines of code (latest
version of Erlang, btw).

Here's the wikipedia entry for green threads. It lists the systems I
listed above, and more: http://en.wikipedia.org/wiki/Green_threads

I'm not trying to "have the last word" here, just saying that it seem to
me some 'major' VMs still use green threads or processes. You are free
to disagree, and if you want the last word, go for it.

--
Posted via http://www.ruby-forum.com/.
Tony Arcieri
2012-07-07 23:05:51 UTC
Permalink
On Sat, Jul 7, 2012 at 12:57 AM, rex goxman <***@ruby-forum.com> wrote:

> Tony Arcieri wrote in post #1067715:
> > You're right, there is no debate! Pretty much all major virtual machines
> > have moved from green threads to native threads.
>
> Perhaps it depends on the definition of what is "major." I won't get
> into that, everybody has their own definition I guess. But all
> Smalltalk VMs I am aware of still use green threads. Smalltalk VM is
> state of the art and has been developed for decades, so I don't see how
> it couldn't be considered "major."
>

It's more like Smalltalk VMs used to be state-of-the-art decades ago. Sun
hired the Anamorphic team (the creators of Strongtalk) to incorporate their
technology into the JVM. They also hired Cliff Click.

Cliff Click threw away the Strongtalk JIT compiler and rewrote it from
scratch. With the advent of pthreads, which weren't available at the time
these Smalltalk VMs you're referencing were written, green threads were
ditched for native threads. The result was HotSpot, the JVM we know today,
and it's slightly more state-of-the-art than any Smalltalk VM. Azul ran the
JVM on systems with 768 cores and heaps of 512GB or more.

Erlang processes are entirely "green," in the same way that a green
> thread is "green." Yes, nowadays they can be mapped to 'real' threads
> running on multiple cores, and that's a good thing.


Sorry to get pedantic, but the term "green threads" was termed specifically
to distinguish the threading models of systems that don't use native
threads from ones which do (i.e. the opposite of "green threaded" is
"native threaded"). As soon as you have parallel OS threads (i.e. on a
multicore computer) managing the scheduling of multiple userspace
threads/"microthreads", you no longer have a "green threaded" system, you
have one which is using native threads. These sorts of systems have very
different properties from green threaded systems as there is true
parallelism. Different threads in the system will have different views of
memory at the same time.

Erlang used to be green threaded, however with the introduction of the SMP
scheduler in R12B Erlang gained native thread/multicore support and Erlang
processes began to run in parallel.

You are colluding terms and that is what is making the discussion difficult.

--
Tony Arcieri
rex goxman
2012-07-08 09:19:16 UTC
Permalink
Tony Arcieri wrote in post #1067845:
> Erlang used to be green threaded, however with the introduction of the
> SMP
> scheduler in R12B Erlang gained native thread/multicore support and
> Erlang
> processes began to run in parallel.
>
> You are colluding terms and that is what is making the discussion
> difficult.

I am using the terms I see in the literature, and in the links provided
to you above. I am using the terms in the same way the links provided
use the terms.

I have not seen any literature say that Erlang is no longer green
threaded (er, green processed). In fact I was just reading more stuff
today that referred to Erlang as having green processes. Erlang's own
docs say that it has green processes.

I am reading Erlang documentation right now which which states that an
Erlang process doesn't amount to much more than a pointer within the
Erlang VM pointing off to some chunk of code/memory inside the Erlang
VM, which explains why the processes are so lightweight.

Again, it doesn't say it's a pointer pointing off to something OUTSIDE
THE VM. Rather, it points to something WITHIN IT.

Again I say I can spawn off several hundred thousand in a second with my
crappy notebook (I can't do that with pthreads, kernel threads, OS
threads, whatever). Again I say I can have literally millions of the
things running (latest version of Erlang). And while doing this, I can
bring up the OS process viewer, and also view the threads running within
the processes. Guess what? NOTHING CHANGES. There aren't thousands or
millions of new processes or threads being added to the OS. There's the
same processes/threads that were there before. In other words, the OS
doesn't know about any of these new processes I fired off within Erlang,
and it isn't creating new threads to handle them. But I can bring up a
process viewer within Erlang, and the millions of processes I created
are all right there.

The fact that the Erlang VM can now take advantage of multiple cores and
move these green processes (which are sparked within the VM and live
within the VM) between the cores by moving them between VMs running one
per core (one OS thread per core is the recommended approach) doesn't
mean the processes aren't green. Just because they can now actually run
truly in parallel (because they are running on different VMs which are
running on different cores) doesn't mean they aren't green.

Can we agree that my Erlang code (compiled to Erlang VM bytecode) has to
be run within an Erlang VM (I'm not compiling it to native code)? If
so, then it means that if some kind of OS or kernel thread was used to
model Erlang processes, an Erlang VM would have to be fired up for each
kernel thread to execute my code. You are talking hundreds of thousands
of VMs being created per second, and millions running on the system. Of
course that doesn't happen.

Erlang didn't change the processes. It didn't change the threading. It
added a scheduler and the infrastructure to allow the green processes
living within the VM to be scheduled across VMs running on other cores.
Erlang's own docs recommend running only one VM in a single thread per
core, because it says you aren't going to get any speedup if you add
more threads and more VMs per core.

> Sorry to get pedantic, but the term "green threads" was termed
> specifically
> to distinguish the threading models of systems that don't use native
> threads from ones which do (i.e. the opposite of "green threaded" is
> "native threaded").

All systems have always used native threads at some point - otherwise
the systems couldn't run at all. At the end of the day, there has
always been and always will be a native thread running somewhere. So
the term "green threaded" doesn't distinguish between systems which
don't use native threads from ones which do, because at the end of the
day they all do. The term "green threaded" (or in Erlang's case, "green
processed") refers to whether or not and how virtual threads or
processes being created and living in the VM map to 'real threads' in
the OS.

Therefore, if you have a system that spawns one 'real thread' (call it a
kernel thread, a pthread, whatever) on the OS for each thread that is
spawned in the VM, then it is not green threaded - the threads are OS
threads. If you have a system that spawns no 'real threads' on the OS
for any threads created in the VM, you have a green threaded system.

> As soon as you have parallel OS threads (i.e. on a
> multicore computer) managing the scheduling of multiple userspace
> threads/"microthreads", you no longer have a "green threaded" system,
> you
> have one which is using native threads.

That's entirely incorrect, because you could have one thread running on
each core, with a single GREEN-THREADED VM running on each of those
threads (x cores, x threads total, x VMs running total). This is what
Erlang does now. The only thing different now than in the past is that
the VMs will communicate back and forth and schedule their GREEN THREADS
across each other.

--
Posted via http://www.ruby-forum.com/.
Tony Arcieri
2012-07-08 17:58:50 UTC
Permalink
On Sun, Jul 8, 2012 at 2:19 AM, rex goxman <***@ruby-forum.com> wrote:

> I am reading Erlang documentation right now which which states that an
> Erlang process doesn't amount to much more than a pointer within the
> Erlang VM pointing off to some chunk of code/memory inside the Erlang
> VM, which explains why the processes are so lightweight.
>

Erlang processes have separate heaps and are independently garbage
collected, however within the SMP scheduler they share the same address
space across cores. While they have an affinity for particular schedulers,
since they operate in a shared address space any scheduler can potentially
execute them.


> Erlang didn't change the processes. It didn't change the threading. It
> added a scheduler and the infrastructure to allow the green processes
> living within the VM to be scheduled across VMs running on other cores.
> Erlang's own docs recommend running only one VM in a single thread per
> core, because it says you aren't going to get any speedup if you add
> more threads and more VMs per core.
>

You're colluding the word "virtual machine" with schedulers running within
the virtual machine. If I launch BEAM for example:

$ erl
Erlang R14B04 (erts-5.8.5) [source] [64-bit] [smp:8:8] [rq:8]
[async-threads:0] [hipe] [kernel-poll:false]

This is a single instance of the Erlang virtual machine. However you will
note smp:8 and rq:8. This is because this single instance of the Erlang
virtual machine is running 8 scheduler threads, one for each core of my
computer:

Eshell V5.8.5 (abort with ^G)
1> erlang:system_info(schedulers).
8


> That's entirely incorrect, because you could have one thread running on
> each core, with a single GREEN-THREADED VM running on each of those
> threads (x cores, x threads total, x VMs running total). This is what
> Erlang does now. The only thing different now than in the past is that
> the VMs will communicate back and forth and schedule their GREEN THREADS
> across each other.


Again, there's only one instance of BEAM, i.e. there is only one virtual
machine, however there are 8 schedulers running inside it. These schedulers
each have their own thread, however they share an address space and contend
on things like memory allocation (again, because there's only one virtual
machine with a single pool of resources that much be shared among
schedulers).

In the past, when Erlang really did use green threads, it was necessary to
run a single Erlang VM per CPU core and use distributed Erlang (even in a
single system) to get multicore parallelism. However, now that Erlang has
an SMP scheduler, one Erlang VM can run a scheduler thread per CPU core and
affect multicore parallelism that way.

--
Tony Arcieri
rex goxman
2012-07-08 19:06:08 UTC
Permalink
Tony Arcieri wrote in post #1067919:
> Again, there's only one instance of BEAM, i.e. there is only one virtual
> machine, however there are 8 schedulers running inside it. These
> schedulers
> each have their own thread, however they share an address space and
> contend
> on things like memory allocation (again, because there's only one
> virtual
> machine with a single pool of resources that much be shared among
> schedulers).
>
> In the past, when Erlang really did use green threads, it was necessary
> to
> run a single Erlang VM per CPU core and use distributed Erlang (even in
> a
> single system) to get multicore parallelism. However, now that Erlang
> has
> an SMP scheduler, one Erlang VM can run a scheduler thread per CPU core
> and
> affect multicore parallelism that way.

Ah! I'll take your word for this, and assume my Erlang distribution
isn't as updated as I thought it was (could have sworn I had the
latest)! Apparently I've been doing the older method of "running a
single VM per core" to achieve parallelism, and this is no longer
necessary. Got it.

Now that that's cleared up, I think we seem to be using different terms
to describe essentially the same thing. For you, it seems no threads
are green anywhere if a VM or scheduler runs a native thread per core to
achieve parallelism. It seems you call the whole shebang "native
threaded."

For me, I draw a line between those millions of threads living in the
VM, and the one native scheduler thread per core. I call the things in
the VM "green threads," and the things the scheduler is running "real
threads" or "kernel threads" or "OS threads" or "native threads" or
whatever. Furthermore, if there are what I call "green threads"
anywhere, I say the whole shebang "has green threads" or "is green
threaded," regardless of whether or not parallelism is achieved by a
scheduler running a kernel thread per core.

If this is true, and we actually agree as to what's going on (albeit
using different terms), I think we can shake hands and call it a day at
this point. And again, thanks for the updated info.

--
Posted via http://www.ruby-forum.com/.
Sam Duncan
2012-07-09 06:34:11 UTC
Permalink
On 07/09/2012 05:58 AM, Tony Arcieri wrote:
>
> Again, there's only one instance of BEAM, i.e. there is only one
> virtual machine, however there are 8 schedulers running inside it.
> These schedulers each have their own thread, however they share an
> address space and contend on things like memory allocation (again,
> because there's only one virtual machine with a single pool of
> resources that much be shared among schedulers).
>
> In the past, when Erlang really did use green threads, it was
> necessary to run a single Erlang VM per CPU core and use distributed
> Erlang (even in a single system) to get multicore parallelism.
> However, now that Erlang has an SMP scheduler, one Erlang VM can run a
> scheduler thread per CPU core and affect multicore parallelism that way.
>
> --
> Tony Arcieri
>

All interesting stuff. This lead me to another interesting read
elaborating on this somewhat:
http://erlang.2086793.n4.nabble.com/Some-facts-about-Erlang-and-SMP-td2108770.html

So that OTP R12B release was running smp mode by default - I wonder how
far back the smp switch was available. I seem to remember running up
rabbits on earlier releases and I guess we must've been using that
option (perhaps lshift scripts did that for us?). Sorry, all, for the
continued digression from 'Ruby Talk'.

Sam
Kirk Haines
2012-07-08 19:07:31 UTC
Permalink
On Sun, Jul 8, 2012 at 3:19 AM, rex goxman <***@ruby-forum.com> wrote:

> I am reading Erlang documentation right now which which states that an
> Erlang process doesn't amount to much more than a pointer within the
> Erlang VM pointing off to some chunk of code/memory inside the Erlang
> VM, which explains why the processes are so lightweight.

And here is, I think, the crux of the cross communication.

It's pretty trivial to use Ruby Proc objects in exactly this way.
Write yourself a simple ProcScheduler, and you can, in Ruby, have very
lightweight green "processes". You can spawn a hundred thousand in a
second, and depending on what they are doing, all hundred thousand can
run in the same second.

Create a subclass of the Proc that you call a ScheduleableProc, add a
few methods to control runnable states, and to indicate whether a
given green process is alive or dead, and you can have a scheduler
that lets GC clean up those dead green processes, while the processes
themselves can manipulate whether or not they are runnable, and can
die when no longer needed.

Voila! Very lightweight "processes" that are similar in concept to the
kind of green threads or processes that you continue to refer to.

It's not really the same thing that Tony is talking about, though.


Kirk Haines
Robert Klemme
2012-07-09 06:05:03 UTC
Permalink
On Fri, Jul 6, 2012 at 2:40 PM, rex goxman <***@ruby-forum.com> wrote:
> Robert Klemme wrote in post #1067663:
>> So far rex provides a solution he wants
>> to use but I cannot really see the reasoning behind it.
>
> *Sigh*. I did not provide a "solution I want to use." I provided a
> CRAPPY EXAMPLE off the top of my head that was advertised as a CRAPPY
> EXAMPLE before giving the CRAPPY EXAMPLE.

I am sorry, but you are wrong: I am not referring to that example.
You said you wanted to use green threads right from the start. That's
a solution to a problem but not a problem.

> I do not intend to divulge any real use cases for green threads because
> they are intuitively obvious, apparent, easy to find or dream up for
> one's self, and the literature is abundant and easily available. It's
> sort of like being asked to give a use case for a hammer. I'm not here
> to educate. If people want education, it's up to them to get it, not up
> to me to provide it.

Actually it's not that simple. A use case for green threads should
have specific properties that prevent usage of kernel threads or make
it less optimal for the case at hand. I provided one such case (i.e.
platform does not support kernel threads) and I doubt there are so
many others. That's what I asked for other use cases. Of course
there are tons of use cases for concurrent processing but that's not
really the point.

But by now I believe the discussion has uncovered that what you really
want is pieces of code with not too much overhead. Kirk gave an
example, Fibers might be another one. Eventually you can view any
object as a "green thread" in the way of that Erlang definition (which
I don't know) you gave: "pointer within the Erlang VM pointing off to
some chunk of code/memory inside the Erlang VM".

Regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
rex goxman
2012-07-09 08:32:29 UTC
Permalink
Robert Klemme wrote in post #1067956:
> Eventually you can view any
> object as a "green thread" in the way of that Erlang definition (which
> I don't know) you gave: "pointer within the Erlang VM pointing off to
> some chunk of code/memory inside the Erlang VM".

What I'm wondering now (and someone who knows is welcome to answer) is
that since we now know I have a totally different definition of "what
constitutes green threads" than some here, does Ruby in fact have green
threads according to my definition? I was told "no" before, and
accepted that answer, but the point is, I was probably told no by
someone using a different definition than me.

Some questions someone can answer which will be helpful:

1. When a thread is created and used with the Thread class, does a new
kernel thread or native thread have to be spawned to deal with it?

2. Related to the first question, would it be common or the norm to have
as many kernel threads spawned as threads created with the Thread class?
What I'm asking is, say you make a loop which creates AND STORES a few
hundred thousand threads from the Thread class. Have you just created a
few hundred thousand kernel or native threads, meaning I can go out to
the OS and see these things in a process or thread viewer? If it helps,
assume this is either a 1 core processor, or a 2-4 core processor (in
other words, the number of Threads you create are huge compared to the
number of cores).

If the answers are "yes" and "yes" I will say Ruby doesn't have green
threads any longer. If the answers are "no" and "no" I will say "ah,
Ruby kept the green threads after all."

--
Posted via http://www.ruby-forum.com/.
Robert Klemme
2012-07-09 09:03:20 UTC
Permalink
On Mon, Jul 9, 2012 at 10:32 AM, rex goxman <***@ruby-forum.com> wrote:
> Robert Klemme wrote in post #1067956:
>> Eventually you can view any
>> object as a "green thread" in the way of that Erlang definition (which
>> I don't know) you gave: "pointer within the Erlang VM pointing off to
>> some chunk of code/memory inside the Erlang VM".
>
> What I'm wondering now (and someone who knows is welcome to answer) is
> that since we now know I have a totally different definition of "what
> constitutes green threads" than some here, does Ruby in fact have green
> threads according to my definition? I was told "no" before, and
> accepted that answer, but the point is, I was probably told no by
> someone using a different definition than me.

Just as clarification: my definition of a "green thread" includes a
program counter (into code which records current position of execution
for the time the thread lies dormant) and a stack (which records the
call chain). If you do not need to interrupt execution of a task you
do not need these and a simple reference to an object and method or
lambda is sufficient.

> Some questions someone can answer which will be helpful:
>
> 1. When a thread is created and used with the Thread class, does a new
> kernel thread or native thread have to be spawned to deal with it?

>= 1.9: yes
<1.9: no

> 2. Related to the first question, would it be common or the norm to have
> as many kernel threads spawned as threads created with the Thread class?
> What I'm asking is, say you make a loop which creates AND STORES a few
> hundred thousand threads from the Thread class. Have you just created a
> few hundred thousand kernel or native threads, meaning I can go out to
> the OS and see these things in a process or thread viewer? If it helps,
> assume this is either a 1 core processor, or a 2-4 core processor (in
> other words, the number of Threads you create are huge compared to the
> number of cores).

>= 1.9: yes, more correctly: at least as many. The runtime or some library might create native threads of their own.

> If the answers are "yes" and "yes" I will say Ruby doesn't have green
> threads any longer. If the answers are "no" and "no" I will say "ah,
> Ruby kept the green threads after all."

Well, but there are other things like Fiber and Continuation which
might be more appropriate in this case. If you do not need to ensure
that execution of a task can be interrupted by another tasks execution
then you can simply use procs / lambdas (i.e. pieces of code to
execute) and throw them in a queue served by a thread pool. That's
why we keep asking for the real use case you want to solve.

Cheers

robert


--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
rex goxman
2012-07-09 14:13:21 UTC
Permalink
I believe I have definitive answers now - thanks.

--
Posted via http://www.ruby-forum.com/.
Jan E.
2012-07-05 20:05:55 UTC
Permalink
rex, why are you still here? You don't want to tell your actual reasons
for using green threads, you don't want to hear alternative solutions,
and the responses seem to annoy you.

Then what's the point of this whole discussion? The original question
seems to be answered by now.

--
Posted via http://www.ruby-forum.com/.
Eric Wong
2012-07-05 20:53:28 UTC
Permalink
rex goxman <***@ruby-forum.com> wrote:
> Anyway, to the point. I'd like to use green threads (NOT kernel
> threads) in a Ruby program I'm writing. There is no reason for me to
> use kernel threads, and every reason to use green ones.

You could try linking Ruby with GNU pth (or GNU nPth). I think pth
comes with pthreads stubs, so maybe you can get that working (and
report back your experiences :)

I suspect pth will conflict with Fibers, however.

> If not available, are there any alternatives? I checked into fibers,
> but they are not appropriate for what I want because if an exception
> happens, it happens in the "main thread" I am executing, which I don't
> want.

I know you don't like fibers, but the "neverblock" gem uses Fibers
transparently under 1.9 to provide green threads. However, I'm
not sure how active "neverblock" development is these days.
Continue reading on narkive:
Loading...