Why the sleep statement produces this result for our embedded ruby?

We are testing thread coperation for our embedded ruby. We have a C ruby
extension implementented the following methods
1. longRunningMethod()
2. shortRunningMethod().

Here is a code for the checking the thread cooperation

//file
test.rb

require 'mymodule'

$a = 0;
obj = MyModule::MyClass.new
t1 = Thread.new{$a = obj.veryLongRunningOperation(); puts "doneLong"}
sleep 1
$a = obj.shortOperation()
puts "doneShort"
t1.join

We have ensured that the longRunningMethod takes more than 1sec(5sec)
for execution using nested for loops
As per our understanding, the shortRunningMethod should be completed
first and then longRunningMethod.

However we observed this only when we did not have any sleep command.
But when we introduced the "sleep 1" statement. The longRunningMethod
gets executed first and then shortRunningMethod

Anyone would give us the pointers as to why the sleep statement produces
this result?

[We are using ruby 1.8.6] Thanks in advance.

···

--
Posted via http://www.ruby-forum.com/.

1.8.6 has green threads and does not use native threads. This means
there is no real parallel execution. It may be that the sleep
triggers Ruby's scheduler to pick another thread which happens to be
stuck in the long C function call. If you think about it it's a
reasonable approach because usually any other thread than the sleepy
thread will have to do work to do.

Behavior may be different on 1.9.* since that uses native threads.
However, I would not yet rely on real thread concurrency. For that
you need JRuby. See this test on my machine (4 cores):

10:51:05 ~$ allruby par.rb
CYGWIN_NT-5.1 padrklemme2 1.7.9(0.237/5/3) 2011-03-29 10:10 i686 Cygwin

···

On Tue, Sep 6, 2011 at 10:11 AM, Balasaheb S. <bg.salunke09@yahoo.com> wrote:

We are testing thread coperation for our embedded ruby. We have a C ruby
extension implementented the following methods
1. longRunningMethod()
2. shortRunningMethod().

Here is a code for the checking the thread cooperation

//file
test.rb

require 'mymodule'

$a = 0;
obj = MyModule::MyClass.new
t1 = Thread.new{$a = obj.veryLongRunningOperation(); puts "doneLong"}
sleep 1
$a = obj.shortOperation()
puts "doneShort"
t1.join

We have ensured that the longRunningMethod takes more than 1sec(5sec)
for execution using nested for loops
As per our understanding, the shortRunningMethod should be completed
first and then longRunningMethod.

However we observed this only when we did not have any sleep command.
But when we introduced the "sleep 1" statement. The longRunningMethod
gets executed first and then shortRunningMethod

Anyone would give us the pointers as to why the sleep statement produces
this result?

[We are using ruby 1.8.6] Thanks in advance.

========================================
ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-cygwin]
par 1
  2.484000 0.000000 2.484000 ( 2.499000)
par 2
  5.047000 0.000000 5.047000 ( 5.042000)
par 3
  7.516000 0.000000 7.516000 ( 7.511000)
par 4
  9.906000 0.000000 9.906000 ( 9.905000)

ruby 1.9.2p290 (2011-07-09 revision 32553) [i386-cygwin]
par 1
  1.328000 0.000000 1.328000 ( 1.323000)
par 2
  2.625000 0.000000 2.625000 ( 2.633000)
par 3
  4.094000 0.000000 4.094000 ( 4.080000)
par 4
  5.344000 0.000000 5.344000 ( 5.346000)

jruby 1.6.3 (ruby-1.8.7-p330) (2011-07-07 965162f) (Java HotSpot(TM)
Client VM 1.6.0_27) [Windows XP-x86-java]
par 1
  1.219000 0.000000 1.219000 ( 1.172000)
par 2
  1.218000 0.000000 1.218000 ( 1.218000)
par 3
  1.110000 0.000000 1.110000 ( 1.110000)
par 4
  1.562000 0.000000 1.562000 ( 1.562000)

jruby 1.6.3 (ruby-1.9.2-p136) (2011-07-07 965162f) (Java HotSpot(TM)
Client VM 1.6.0_27) [Windows XP-x86-java]
par 1
  1.390000 0.000000 1.390000 ( 1.390000)
par 2
  1.844000 0.000000 1.844000 ( 1.844000)
par 3
  3.422000 0.000000 3.422000 ( 3.422000)
par 4
  3.719000 0.000000 3.719000 ( 3.719000)

10:52:13 ~$ cat -n par.rb
     1
     2 require 'benchmark'
     3
     4 for par in 1 .. 4
     5 printf "par %2d\n", par
     6
     7 puts(Benchmark.measure do
     8 th = (1..par).map do
     9 Thread.new { 10_000_000.times { 1 + 2 }}
    10 end
    11
    12 th.each {|t| t.join}
    13 end)
    14 end
    15
    16
10:52:21 ~$

Note that in spite of native threads and absence of IO ruby 1.9.2 does
not scale better than ruby 1.8.7.

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/