From: Takaaki Tateishi Date: 2002-05-17T23:55:12+09:00 Subject: [ruby-dev:17130] Re: Thread: deadlock trouble At Fri, 17 May 2002 14:47:53 +0900, > 以下に示すようなケースなんですが,どうにか改修する手はないものでしょうか? 単純な方法ですが,以下に類似した方法で解決できるでしょうか? トップレベルでスレッドのためのキューを作ります.コールバック 内でスレッドを実行したいときには,このキューにprocオブジェク トを入れます. トップレベルのスレッドにおいて,一定時間やあるトリガに反応し てキューに溜ったprocオブジェクトを順にスレッドとして実行する ようにします. require 'tk' require 'thread' class TkThread QUEUE = [] MUTEX = Mutex.new THREAD = Thread.new{ while( true ) sleep MUTEX.synchronize{ QUEUE.each{|cb| Thread.new{ cb.call() } } QUEUE.clear } end } def TkThread.new(v=nil) MUTEX.synchronize{ QUEUE.push(Proc.new{ yield(v)}) } THREAD.wakeup end end b1 = TkButton.new(nil, 'text'=>"b1:{p 'b1'}", 'command'=>proc{p 'b1'}).pack b2 = TkButton.new(nil, 'text'=>"b2:{Thread{p 'b2'}}", 'command'=>proc{Thread.new{p 'b2'}.value}).pack TkButton.new(nil, 'text'=>'{b1.invoke}', 'command'=>proc{b1.invoke}).pack TkButton.new(nil, 'text'=>'{b2.invoke}', 'command'=>proc{b2.invoke}).pack TkButton.new(nil, 'text'=>'Thread{b1.invoke}', 'command'=>proc{TkThread.new{b1.invoke}}).pack TkButton.new(nil, 'text'=>'Thread{b2.invoke}', 'command'=>proc{TkThread.new{b2.invoke}}).pack Tk.mainloop -- Takaaki Tateishi