No timeslicing?

I decided its high time I tried to learn threads again,
and my best chance is to do it in Ruby.

But the scheduler doesnt seem to want to run any threads
until the previous ones have finished:

------------------8<------------------------

0rasputin@lb:rasputin$ cat freds.rb
symbols = %w( = ^ V < > @ # ! )
threads = []
string = “”

symbols.each { |symbol|
threads << Thread.new(symbol) do |sym|
9.times { string << sym }
end
}

threads.each { |w| threads.join }
puts string
0rasputin@lb:rasputin$ ruby freds.rb
=========^^^^^^^^^VVVVVVVVV<<<<<<<<<>>>>>>>>>@@@@@@@@@#########!!!
0rasputin@lb:rasputin$

------------------8<------------------------

The pickaxe example at:
http://www.rubycentral.com/book/tut_threads.html#UA
, which is almost identical, seems to timeslice ok.

And if I scatter some magic Thread.pass dust in there it behaves itself.
Is it just that the threads exit too soon to get suspended?

This is on NetBSD 1.6Z with Ruby 1.6.8 and todays CVS.

···


$100 invested at 7% interest for 100 years will become $100,000, at
which time it will be worth absolutely nothing.
– Lazarus Long, "Time Enough for Love"
Rasputin :: Jack of All Trades - Master of Nuns

But the scheduler doesnt seem to want to run any threads
until the previous ones have finished:

This might be related to the scheduler not doing any thread switches in
C functions. (It can only switch threads between them.)

I would like to see this loosened up, but I understand that it might be
difficult to implement on all available platforms.

symbols = %w( = ^ V < > @ # ! )
threads =
string = “”

symbols.each { |symbol|
threads << Thread.new(symbol) do |sym|
9.times { string << sym }
end
}

threads.each { |w| threads.join }
puts string

Maybe Thread.pass can help you. It’s also in the pickaxe.

BTW: shouldn’t it be “w.join”?

Regards,
Pit

“Rasputin” rasputnik@hellooperator.net schrieb im Newsbeitrag
news:20040121170047.GA20259@lb.tenfour…

I decided its high time I tried to learn threads again,
and my best chance is to do it in Ruby.

But the scheduler doesnt seem to want to run any threads
until the previous ones have finished:

That’s just an accidental thing. Your threads probably don’t do enough to
trigger a context switch.

------------------8<------------------------

0rasputin@lb:rasputin$ cat freds.rb
symbols = %w( = ^ V < > @ # ! )
threads =
string = “”

symbols.each { |symbol|
threads << Thread.new(symbol) do |sym|
9.times { string << sym }
end
}

threads.each { |w| threads.join }
puts string
0rasputin@lb:rasputin$ ruby freds.rb
=========^^^^^^^^^VVVVVVVVV<<<<<<<<<>>>>>>>>>@@@@@@@@@#########!!!
0rasputin@lb:rasputin$

You need to synchronize access to the shared resource ‘string’. And you
joined on the wrong variable:

Robert@Babelfish2 ~/test
$ ruby t.rb
=========^^^^^^^^^VVVVVVVVV<<<<<<<<<>>>#########@@@@@@@@@>>!!!>>>>

Robert@Babelfish2 ~/test
$ cat t.rb
require ‘Thread’

symbols = %w( = ^ V < > @ # ! )
threads =
string = “”
mutex = Mutex.new

symbols.each { |symbol|
threads << Thread.new(symbol) do |sym|
9.times { mutex.synchronize { string << sym } }
end
}

threads.each { |w| w.join }
puts string

Robert@Babelfish2 ~/test
$

Regards

robert
···

------------------8<------------------------

The pickaxe example at:
http://www.rubycentral.com/book/tut_threads.html#UA
, which is almost identical, seems to timeslice ok.

And if I scatter some magic Thread.pass dust in there it behaves itself.
Is it just that the threads exit too soon to get suspended?

This is on NetBSD 1.6Z with Ruby 1.6.8 and todays CVS.


$100 invested at 7% interest for 100 years will become $100,000, at
which time it will be worth absolutely nothing.
– Lazarus Long, “Time Enough for Love”
Rasputin :: Jack of All Trades - Master of Nuns

Pit Capitain wrote:

symbols = %w( = ^ V < > @ # ! )
threads =
string = “”

symbols.each { |symbol|
threads << Thread.new(symbol) do |sym|
9.times { string << sym }
end
}

threads.each { |w| threads.join }
puts string

Maybe Thread.pass can help you. It’s also in the pickaxe.

BTW: shouldn’t it be “w.join”?

Ack! - just my luck to confuse two completely different methods on
two completely different objects that just happen to share a name

  • thanks!

Think the odd output was an artefact of the short duration
of each thread - if I add a delay the output is what I’d expect:

-------------------------------8<------------------------------

0rasputin@lb:rasputin$ cvs diff freds.rb
Index: freds.rb

···

===================================================================
RCS file: /data/cvsroot/rasputin/freds.rb,v
retrieving revision 1.3
diff -r1.3 freds.rb
7c7
< 9.times { string << sym }

            9.times { string << sym ; sleep(0.2) }

0rasputin@lb:rasputin$ ruby freds.rb
=^V<>@#!!#@><V^=!#@><V^=!#@><V^=!#@><V^=!#@><V^=!#@><V^=!#@><V^=!#@><V^=
0rasputin@lb:rasputin$

-------------------------------8<------------------------------

Thanks to all the sanity checkers!


Rasputin :: Jack of All Trades - Master of Nuns