Joel VanderWerf
10/25/2006 6:47:00 PM
Charles Oliver Nutter wrote:
> Paul Lutus wrote:
>> I tried to think of an explanation apart from the obvious one, but it
>> seems
>> I am wrong. I think the fact that they are all sleeping their time
>> away may
>> partly explain this outcome, but the threads are clearly running
>> concurrently.
>>
>> Threads that are not sleeping may not live up to the promise of this
>> example. My threads tend not to run concurrently, but your example is an
>> excellent refutation.
>
> Threads that are 100% Ruby code will yield and timeslice correctly.
> However they still will never run concurrently, other than timeslicing.
> Threads that make system calls will run sequentially, since system calls
> can't be scheduled by Ruby's thread scheduler. If you have a thread make
> a system call, that call must complete before the thread will yield.
That's true at the C API level, but not always true at the Ruby API
level, as you say...
> There's some trickery with IO in some cases, but for the general case
> this is how it works. You may try JRuby, which has fully concurrent
> native thread support, but not everything in normal Ruby is 100%
> supported yet...and Kernel#system isn't quite perfect yet.
Is select() really trickery? Anyway, in addition to the IO trickery,
there is also a concurrent #system, as this example shows:
$ cat x.rb
t = Thread.new do
system "sleep 1; echo SYSTEM; sleep 1; echo SYSTEM; sleep 1; echo SYSTEM"
end
3.times do
sleep 1
puts "RUBY"
end
t.join
$ ruby x.rb
RUBY
SYSTEM
RUBY
SYSTEM
RUBY
SYSTEM
For some purposes (networking) ruby's threads are pretty good, to a
point. For some other purposes, we can use #fork plus drb. There are
cases where one is SOL though.
We're all looking forward to native threads in future ruby VMs and JRuby.
--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407