From: James Tucker Date: 2010-07-23T22:23:04+09:00 Subject: [ruby-core:31457] Re: [Bug #3606] Thread.stop and puts fail to work as documented. On 23 Jul 2010, at 05:55, Heesob Park wrote: > on Ruby 1.8.6 > > $ ruby -v > ruby 1.8.6 (2009-06-08 patchlevel 369) [i686-linux] > $ ruby -v t1.rb > a > Got here > c > $ ruby -v t2.rb > abc$ ruby -v t3.rb > hey! > $ > > Result > t1.rb ==> success > t2.rb ==> success > t3.rb ==> success This is because threads in 1.8.6 are not really threads. The engine is predictable within the realms of ruby frames. > on Ruby 1.9.1 > > $ ruby -v > ruby 1.9.1p378 (2010-01-10 revision 26273) [i686-linux] > $ ruby t1.rb > aGot here > > c > $ ruby t2.rb > $ ruby t3.rb > $ > > Result > t1.rb ==> fail > t2.rb ==> success > t3.rb ==> fail This could, or should vary, actually. The example code is not thread safe. > On Ruby 1.9.3dev > > duometis02@Duo02:~$ ruby -v > ruby 1.9.3dev (2010-07-22 trunk 28707) [i686-linux] > $ ruby t1.rb > Got herea > > t1.rb:5:in `join': deadlock detected (fatal) > from t1.rb:5:in `
' > $ ruby t2.rb > bat2.rb:5:in `join': deadlock detected (fatal) > from t2.rb:5:in `
' > $ ruby t3.rb > $ So what's happening here is that you're getting to thread.join before the other thread has got to thread.stop. This is a race condition in your code. Threads are hard, and it's regarded that tools like stop, run, join, and pass are very very hard to use in a thread safe way. Assuming that calling Thread.pass with force at least a single expression to run in another thread is not valid. > Interesingly, the following code sometimes works and sometimes failed on Ruby 1.9.3.dev. > t4.rb > ==================================================== > c = Thread.new { Thread.stop; puts "hey!" } > puts "Hi!" > c.wakeup > sleep 1 > ==================================================== > $ ruby -v > ruby 1.9.3dev (2010-07-22 trunk 28707) [i686-linux] > $ ruby t4.rb > Hi! > $ ruby t4.rb > Hi! > hey! > $ ruby t4.rb > Hi! > hey! > $ ruby t4.rb > Hi! As above, this is a race condition. If c.wakeup is called before Thread.stop, then the code will never restart the thread after it stops itself. This is an error in the code, not in the interpreter.