# Newly created thread blocks all others in Ruby 1.8.7 patchlevel 72 on Cygwin

**URL:** <https://www.ruby-forum.com/t/newly-created-thread-blocks-all-others-in-ruby-1-8-7-patchlevel-72-on-cygwin/146267>\
**Category:** Ruby\
**Created:** [August 19, 2008, 5:28pm UTC](https://www.ruby-forum.com/t/newly-created-thread-blocks-all-others-in-ruby-1-8-7-patchlevel-72-on-cygwin/146267 "2008-08-19T17:28:24Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![danmcb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/13edae/32.png) [@danmcb](https://www.ruby-forum.com/u/danmcb)\
**Post date:** [August 19, 2008, 5:28pm UTC](https://www.ruby-forum.com/t/newly-created-thread-blocks-all-others-in-ruby-1-8-7-patchlevel-72-on-cygwin/146267/1 "2008-08-19T17:28:24Z")

</div>

Hello together,

I am using the following Ruby version:

ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-cygwin]

I have problems with threads now that did not occur in Ruby 1.8.6. I  
execute  
the following code (derived from an  
example in the Ruby core documentation):

```
require 'thread'

count1 = count2 = 0
puts "starting thread a"
a = Thread.new do
      loop { count1 += 1 }
    end
a.priority = -1

puts "starting thread b"
b = Thread.new do
      loop { count2 += 1 }
    end
b.priority = -2
sleep 1 #=> 1
Thread.critical = 1

puts "count1: #{count1}"
puts "count2: #{count2}"

```

This code never starts thread b. It seems that thread a blocks all  
other threads once it runs (though its priority is lowered), even the  
main thread.  
If I put a sleep command into the thread a loop, thread b starts, but  
the problem remains, since then thread b blocks all others from  
running.

The Ruby 1.8.7 release notes speak of a change in the mutex  
implementation in C. Could that be a problem?

Thanks for any help  
Daniel

---

<div class="post-metadata">

**Author:** ![danmcb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/13edae/32.png) [@danmcb](https://www.ruby-forum.com/u/danmcb)\
**Post date:** [August 19, 2008, 10:10pm UTC](https://www.ruby-forum.com/t/newly-created-thread-blocks-all-others-in-ruby-1-8-7-patchlevel-72-on-cygwin/146267/2 "2008-08-19T22:10:26Z")

</div>

2008/8/19 Daniel M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> I am using the following Ruby version:
> 
> ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-cygwin]

Hello Daniel, I don’t have 1.8.7 yet, I don’t have cygwin, and…

> I have problems with threads now that did not occur in Ruby 1.8.6.

…and I don’t think that what you see is a problem. It may be that on  
1.8.6 you saw a different behavior, but I still don’t think that the  
new behavior is a problem, because AFAIK Ruby doesn’t guarantee that  
threads with equal priority do get equal time to run. If you create a  
thread with

> a = Thread.new do  
> loop { count1 += 1 }  
> end

then Ruby starts the thread as documented. I think it’s perfectly  
legal that Ruby runs only the new thread without scheduling other  
threads, including the main thread, as long as there’s no other thread  
with higher priority.

> a.priority = -1

If you finally get there, then it should be the main thread again who  
is blocking thread “a”.

> b = Thread.new do  
> loop { count2 += 1 }  
> end

Here the same applies as above. Thread “b” could run all the time.

> b.priority = -2

Now it should be: main thread blocks “a” blocks “b”.

> sleep 1 #=\> 1

Give “a” some more time to run.

> Thread.critical = 1
> 
> puts “count1: #{count1}”  
> puts “count2: #{count2}”
> 
> This code never starts thread b. It seems that thread a blocks all  
> other threads once it runs (though its priority is lowered), even the  
> main thread.

See above. I think that’s ok. What behavior do you expect? Or better:  
what do you want to achieve?

Regards,  
Pit

---

<div class="post-metadata">

**Author:** ![danmcb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/13edae/32.png) [@danmcb](https://www.ruby-forum.com/u/danmcb)\
**Post date:** [August 20, 2008, 9:37am UTC](https://www.ruby-forum.com/t/newly-created-thread-blocks-all-others-in-ruby-1-8-7-patchlevel-72-on-cygwin/146267/3 "2008-08-20T09:37:04Z")

</div>

Hi Pit,

thanks for your response.

The behaviour I expect from threads in general is that they virtually  
run in  
parallel. So I expect each active thread to be at least scheduled, but  
not  
blocked, even if it has a low priority. If there is a total of two  
threads  
that have the same priority, I expect the thread scheduler to assign 50%  
of  
processing resources to each of them. In earlier Ruby versions (e.g.  
1.8.6),  
this is exactly what has happened.

I could reach that behavior in the example before (which is as I stated  
an  
“official” one, since you can also find it in the only ruby core  
documentation of the thread class:  
[class Thread - RDoc Documentation](http://www.ruby-doc.org/core/classes/Thread.html#M000480)) by inserting  
sleep  
statements into the loop-blocks. I could then control the amount of  
processing time for each thread by balancing the sleep times, therefore  
emulating priority. But then I would mimic the behavior that usually  
rubys  
thread scheduler should perform for me.

Best regards  
Daniel

---

<div class="post-metadata">

**Author:** ![danmcb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/13edae/32.png) [@danmcb](https://www.ruby-forum.com/u/danmcb)\
**Post date:** [August 21, 2008, 12:32pm UTC](https://www.ruby-forum.com/t/newly-created-thread-blocks-all-others-in-ruby-1-8-7-patchlevel-72-on-cygwin/146267/4 "2008-08-21T12:32:20Z")

</div>

Hi Daniel.

> The behaviour I expect from threads in general is that they virtually run in  
> parallel. So I expect each active thread to be at least scheduled, but not  
> blocked, even if it has a low priority.

From looking at the source code of 1.8.6 and from running some tests  
this doesn’t seem to be the case. Threads with lower priority are  
blocked as long as there are runnable threads with higher priority.

> If there is a total of two threads  
> that have the same priority, I expect the thread scheduler to assign 50% of  
> processing resources to each of them. In earlier Ruby versions (e.g. 1.8.6),  
> this is exactly what has happened.

Indeed this seems to be the case in 1.8.6, again from looking at the  
source and running some tests. If this doesn’t work in Ruby 1.8.7, you  
should perhaps report it on ruby-core.

> I could reach that behavior in the example before (which is as I stated an  
> “official” one, since you can also find it in the only ruby core  
> documentation of the thread class:  
> [class Thread - RDoc Documentation](http://www.ruby-doc.org/core/classes/Thread.html#M000480)) by inserting sleep  
> statements into the loop-blocks.

AFAIK there’s no official description of Ruby yet. There are projects  
trying to fill this gap with executable specifications.

> I could then control the amount of  
> processing time for each thread by balancing the sleep times, therefore  
> emulating priority. But then I would mimic the behavior that usually rubys  
> thread scheduler should perform for me.

I don’t buy this “should”. The documentation you’ve cited clearly  
says, that higher-priority threads will run before lower-priority  
threads.

Regards,  
Pit

---

<div class="post-metadata">

**Author:** ![danmcb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/13edae/32.png) [@danmcb](https://www.ruby-forum.com/u/danmcb)\
**Post date:** [August 22, 2008, 1:49pm UTC](https://www.ruby-forum.com/t/newly-created-thread-blocks-all-others-in-ruby-1-8-7-patchlevel-72-on-cygwin/146267/5 "2008-08-22T13:49:21Z")

</div>

Hi Pit,

thanks again for the response. I backgraded to Ruby 1.8.6 to make some  
tests too, the behavior is as you have described it. Here the test  
code I have used:

Thread.main.priority = 0  
count1 = count2 = 0

a = Thread.new do  
puts “starting thread a”  
Thread.current.priority = -1  
loop { count1 += 1 }  
end

b = Thread.new do  
puts “starting thread b”  
Thread.current.priority = -1  
loop { count2 += 1}  
end

puts “stalling main thread for 1 second”  
sleep 1

a.kill; b.kill  
puts “count1: #{count1}”  
puts “count2: #{count2}”

On Ruby 1.8.6 I get the following output:

starting thread a  
starting thread b  
stalling main thread for 1 second  
count1: 953760  
count2: 953753

So this is fine and what I expected (if I lower thread b priority to  
-2, count2 drop to absolute 0. This is quite awful, but ok, I’ll stop  
complaining ;-). On Ruby 1.8.7 however, I just see:

starting thread a  
starting thread b  
stalling main thread for 1 second

No more output from here on. It seems that the sleep statement does not  
return.

Thanks however for your help.

Regards  
Daniel

---

<div class="post-metadata">

**Author:** ![danmcb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/13edae/32.png) [@danmcb](https://www.ruby-forum.com/u/danmcb)\
**Post date:** [August 22, 2008, 4:31pm UTC](https://www.ruby-forum.com/t/newly-created-thread-blocks-all-others-in-ruby-1-8-7-patchlevel-72-on-cygwin/146267/6 "2008-08-22T16:31:12Z")

</div>

On Aug 19, 2008, at 9:22 AM, Daniel M. wrote:

> b = Thread.new do  
> This code never starts thread b. It seems that thread a blocks all  
> other threads once it runs (though its priority is lowered), even the  
> main thread.  
> If I put a sleep command into the thread a loop, thread b starts, but  
> the problem remains, since then thread b blocks all others from  
> running.

that code looks completely non-deterministic to me and i’ve had  
similar issues many times in the past. i think the fundamental error  
is mistaking the creation of a thread for scheduling it. i’ve used  
the following pattern many times to force my code to know that a  
thread has started processing before continuing:

cfp:~ \> ruby186 a.rb  
starting thread a  
starting thread b  
count1: 4580083  
count2: 44732

cfp:~ \> ruby187 a.rb  
starting thread a  
starting thread b  
count1: 4394267  
count2: 37032

cfp:~ \> cat a.rb

require ‘thread’

q = Queue.new  
count1 = count2 = 0

a =  
Thread.new do  
puts “starting thread a”  
q.push Thread.current  
loop { count1 += 1 }  
end

a = q.pop # wait for the thread to start  
a.priority = -1

b =  
Thread.new do  
puts “starting thread b”  
q.push Thread.current  
loop { count2 += 1 }  
end

b = q.pop # wait for the thread to start  
b.priority = -2

sleep 1 #=\> 1  
Thread.critical = 1

puts “count1: #{count1}”  
puts “count2: #{count2}”

i’m sorry that i cannot test this on cygwin so i’m not _sure_ it’s the  
issue. but to me it simply looks like non-deterministic code. in  
fact, even the code above has a race condition, i only force the  
program to ensure each thread calls puts - there is nothing to make  
sure that stdout has been flushed or that the increments have run in  
the loop. to do that i think you’d need something like this

cfp:~ \> cat a.rb  
require ‘thread’

q = Queue.new  
count1 = count2 = 0

a =  
Thread.new do  
STDERR.puts “starting thread a”  
loop do  
count1 += 1  
q.push Thread.current if count1 == 1  
end  
end

a = q.pop # wait for the thread to start  
a.priority = -1

b =  
Thread.new do  
puts “starting thread b”  
q.push Thread.current  
loop do  
count2 += 1  
q.push Thread.current if count2 == 1  
end  
end

b = q.pop # wait for the thread to start  
b.priority = -2

Thread.critical = 1

puts “count1: #{count1}”  
puts “count2: #{count2}”

cfp:~ \> ruby186 a.rb  
starting thread a  
starting thread b  
count1: 19297  
count2: 28490

cfp:~ \> ruby187 a.rb  
starting thread a  
starting thread b  
count1: 17435  
count2: 24603

i’d be curious how that fairs on cygwin. notice that the sleep is not  
required with the queues.

regards.

a @ [http://codeforpeople.com/](http://codeforpeople.com/)
