Ruby and threads

J

John Wells

Guys,

Was looking through the forums at ruby-ide.com when I noticed the
following comment:

"Unfortunately i can't use ruby for scripting/extending/implementing as
ruby does not work with multiple native threads and i already have one
ruby thread that is doing the background parsing."

Can anyone elaborate on this? How does it effect folks developing in
Ruby, and curiously, why does Python seem to support it and Ruby doesn't?

Thanks for your insight!

John
 
D

Daniel Amelang

Hi John,

Quick answer: There are plans (and people working on them right now)
to support native threads.

This has been discussed numerous times on this list, so your best bet
is to search the list archives for 'native threads' if you're
interested in reading a discussion about it.

Dan
 
P

Phil Tomson

Guys,

Was looking through the forums at ruby-ide.com when I noticed the
following comment:

"Unfortunately i can't use ruby for scripting/extending/implementing as
ruby does not work with multiple native threads and i already have one
ruby thread that is doing the background parsing."

Can anyone elaborate on this? How does it effect folks developing in
Ruby, and curiously, why does Python seem to support it and Ruby doesn't?

It's because there are a lot of globals defined in the Ruby interpreter so
it's not threadable (native threadable, that is).

However, recently there have been some interesting developments with an
experimental Ruby interpreter called Sydney. Here's a quote from the
weblog page where it was announced:

"Sydney is an experimental fork of 1.8.2 that adds a number of features,
such as:

* Native OS Threads (Thread::OS). These do not replace the normal
Threads, and allow for MxN thread setups (see
test/sydney/test_osthread.rb#test_mxn). There is a lot to be said about
these, so lets move on for now.
...

In getting OS threads implement, the core of the interpretter has been
modified to be reentrant and thread-safe, allowing mulitple threads to
run concurrently.

All globals have been cleaned up and moved into a unified ruby_state
struct (accessable directly in the form of Ruby::State objects). "

This way you can get the best of both worlds - Ruby's current
cross-platform 'green' threads and native threads if you need them. I
hope that this makes it back into the 'official' Ruby interpreter.



Phil
 
P

Phil Tomson

It's because there are a lot of globals defined in the Ruby interpreter so
it's not threadable (native threadable, that is).

However, recently there have been some interesting developments with an
experimental Ruby interpreter called Sydney. Here's a quote from the
weblog page where it was announced:

"Sydney is an experimental fork of 1.8.2 that adds a number of features,
such as:

* Native OS Threads (Thread::OS). These do not replace the normal
Threads, and allow for MxN thread setups (see
test/sydney/test_osthread.rb#test_mxn). There is a lot to be said about
these, so lets move on for now.
...

In getting OS threads implement, the core of the interpretter has been
modified to be reentrant and thread-safe, allowing mulitple threads to
run concurrently.

All globals have been cleaned up and moved into a unified ruby_state
struct (accessable directly in the form of Ruby::State objects). "

This way you can get the best of both worlds - Ruby's current
cross-platform 'green' threads and native threads if you need them. I
hope that this makes it back into the 'official' Ruby interpreter.


Ooops. Forgot to include a link to Sydney:

http://blog.fallingsnow.net/articles/category/Sydney

Phil
 
Y

Yohanes Santoso

John Wells said:
Guys,

Was looking through the forums at ruby-ide.com when I noticed the
following comment:

"Unfortunately i can't use ruby for scripting/extending/implementing as
ruby does not work with multiple native threads and i already have one
ruby thread that is doing the background parsing."

Can anyone elaborate on this? How does it effect folks developing in
Ruby, and curiously, why does Python seem to support it and Ruby
doesn't?

I can come up with only two significant downsides of green threading
that ruby has:

1. inability to use multiple cpus to run multiple threads,
2. blocked process.

(2) is usually caused by disk io waiting for disk readiness. this is
not monitorable in most unix (windows too?). the whole process
would block until the disk is ready.

(2) is also caused by certain functions in some c extension libraries.

python's supports for native threading effectively eliminates these
two downsides, but also introduce another downside. threads executing
python code would need to obtain the global interpretter lock. This
means at any given moment, there is still only one thread executing
python code. In addition, the cost of acquiring the lock increases
with the number of threads. But this setup eliminates (1) and (2).

YS.
 
A

Adam P. Jenkins

Yohanes said:
I can come up with only two significant downsides of green threading
that ruby has:

1. inability to use multiple cpus to run multiple threads,
2. blocked process.

(2) is usually caused by disk io waiting for disk readiness. this is
not monitorable in most unix (windows too?). the whole process
would block until the disk is ready.

(2) is also caused by certain functions in some c extension libraries.

python's supports for native threading effectively eliminates these
two downsides, but also introduce another downside. threads executing
python code would need to obtain the global interpretter lock. This
means at any given moment, there is still only one thread executing
python code.

This certainly isn't an inherent problem with native threads; there is
no reason in principle that an interpreted language couldn't let
multiple threads execute simultaneously if the interpreter were written
correctly. If what you say is true, that only one Python thread can be
executing at a time, then Python still can't really take advantage of
multiple CPUS.

Adam
 
Y

Yohanes Santoso

Adam P. Jenkins said:
This certainly isn't an inherent problem with native threads; there is
no reason in principle that an interpreted language couldn't let
multiple threads execute simultaneously if the interpreter were
written correctly.

Adam,

You are right that this isn't an inherent problem with native
threads. There are language implementations that use interpreted
technique that locks only the relevant interpreter state data, and not
the whole interpreter. These implementations would be able to take
advantage of multiple CPUs in a 'better' way than an implementation
that locks the whole interpreter. Examples of these implementations
would be sun's jvm which can interpret the bytecode in multiple CPUs
concurrently.

<sidebar>languages are neither compiled nor interpreted; but an
implementation of a language is compiled or interpreted or both
(e.g. JIT)) said:
If what you say is true, that only one Python
thread can be executing at a time, then Python still can't really take
advantage of multiple CPUS.

Adam

What I said before applies to pre-2 python. I am not sure what's the
current state is. Even if it is still the same, it would still be able
to take advantage of multiple CPUs, although not directly, as there
are other things to do beside executing code.

For example, think of reading from a socket. At the OS level, that
would involve copying of memory from the eth card's memory to the main
RAM (unless your eth card&driver are doing DMA). Doing reads from two
different native threads would likely result in two CPUs doing the
copying.

While with current ruby implementation, there is only one copying
going on at a time.

You can test whether current python implementation still use a global
interpreter lock or not by trying to span multiple threads, each doing
some CPU-intensive computation (e.g. repeatedly increasing the value
of some thread-local variable) on a MP machine, and then comparing the
result with the same program on the same MP machine with less number
of CPUs activated.

I can't do the above test since I don't have access to a MP machine
anymore. So, I'm waiting for your response.

Yours,
YS.
 
A

Adam P. Jenkins

Yohanes said:
You can test whether current python implementation still use a global
interpreter lock or not by trying to span multiple threads, each doing
some CPU-intensive computation (e.g. repeatedly increasing the value
of some thread-local variable) on a MP machine, and then comparing the
result with the same program on the same MP machine with less number
of CPUs activated.

I can't do the above test since I don't have access to a MP machine
anymore. So, I'm waiting for your response.

Hmm, I just tried on an 8p ia64 machine running Linux, with python 2.3.
I tried the following program, which starts 4 threads, which each
execute a function which just busy loops. I then watched what went on
in "top" in another terminal. If I execute the function in just one
thread, then one of the CPUs goes to 99% usage. If I execute 4 threads,
then 4 of the CPUs go to about %20 usage. So it does seem that a global
interpreter lock is still being used in Python's implementation. Too
bad, though I suppose I wasn't about to go and write computationally
intensive code in Python anyway.

from threading import Thread

nthreads = 4

def busyloop(n=2**26):
i = 0
while i < n:
i = i + 1

threads = []

for i in range(nthreads):
th = Thread(target=busyloop)
th.start()
threads.append(th)

for th in threads:
th.join()
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,176
Messages
2,570,950
Members
47,500
Latest member
ArianneJsb

Latest Threads

Top