Issue #5195 has been updated by Motohiro KOSAKI.


??潟?????????????障???????????鐚?鐚???????????????障??翫???????????workaround??с??????????? 鐚?鐚?篏???榊????????鴻????宴?若?鴻?с??????????? ???????1.9.3???backport??????障???????с????????
----------------------------------------
Bug #5195: Queue#pop???sleep??????????thread???wakeup????????????Queue???@waiting???????thread???push????????????障??
http://redmine.ruby-lang.org/issues/5195

Author: Masaki Matsushita
Status: Closed
Priority: Normal
Assignee: Motohiro KOSAKI
Category: lib
Target version: 1.9.x
ruby -v: ruby 1.9.4dev (2011-08-14 trunk 32972) [x86_64-linux]


=begin
罨<?????????潟?若?????絎?茵???????????
 
 require 'thread'
 
 queue = Queue.new
 
 t1 = Thread.start { queue.pop; p 1 }
 
 nil until t1.stop?
 t1.wakeup
 nil until t1.stop?
 
 t2 = Thread.start { queue.pop; p 2 }
 
 nil until t1.stop? && t2.stop?
 
 p t1, t2
 queue.instance_eval{ p @waiting }
 
 2.times{ queue.push(nil) }
 
 t1.join
 t2.join

篁ヤ???????????????????????障?????

 #<Thread:0x000000014d8108 sleep>
 #<Thread:0x000000014d8090 sleep>
 [#<Thread:0x000000014d8108 sleep>, #<Thread:0x000000014d8108 sleep>, #<Thread:0x000000014d8090 sleep>]
 1
 /home/masaki/ruby/queue_waiting.rb:22:in `join': deadlock detected (fatal)
 from /home/masaki/ruby/queue_waiting.rb:22:in `<main>'

lib/thread.rb???184茵?????Queue#pop???篁ヤ?????????????臂???????????障????????

 def pop(non_block=false)
    @mutex.synchronize{
      while true
        if @que.empty?
          raise ThreadError, "queue empty" if non_block
          @waiting.push Thread.current
          @mutex.sleep
        else
          return @que.shift
        end
      end
    }
  end

??????潟?若????с??Queue#pop???sleep??????????thread???wakeup???????????????≪??push羝???帥??Thread.current??????綺?@waiting???push????????????障????障?????
????????????違?с??????с??????????????

patch???羞私???????障?????
??????patch??с????????c?????障?????с??????????後慎?????障???????????

 require 'benchmark'
 require 'thread'
 
 def push_pop
   q = Queue.new
   time = 100000
 
   push = Thread.start do
     time.times { q.push(nil) }
   end
 
   pop = Thread.start do
     time.times { q.pop }
   end
 
   push.join
   pop.join
 end
 
 Benchmark.bm do |x|
   x.report("before") { push_pop }
 end

????????????潟???????若???篏???c?荅??????帥????????????
patch????篁??????

 user     system      total        real
 0.460000   0.000000   0.460000 (  0.452595)
 0.500000   0.040000   0.540000 (  0.529834)
 0.410000   0.030000   0.440000 (  0.433928)

????????

 user     system      total        real
 0.480000   0.060000   0.540000 (  0.505939)
 0.450000   0.000000   0.450000 (  0.449451)
 0.430000   0.010000   0.440000 (  0.435586)

????c?????с???????祉??????????c???????????????с?????
patch?????????test/thread/test_queue.rb????????鴻????障?????

=end


-- 
http://redmine.ruby-lang.org