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