From: keiju@... (Keiju ISHITSUKA) Date: 1998-04-08T18:44:02+09:00 Subject: [ruby-list:7376] [Q] Thread けいじゅ@日本ラショナルソフトウェアです. スレッドに関して, どうも良く分からないので教えて下さい. irbの話しなのですが, 内部で新しいirbを立ちあげる時にthreadを起動してい ます. 子を立ちあげると, 親irbはThread.stopします. そして, 子irbを抜け ると, 親irbをrunするようにしています. 以下のようなコードになっています. # irb起動 def IRB.irb(file = nil, *main) workspace = IRB.workspace_binding(*main) if main.empty? main = eval("self", workspace) else main = main[0] end irb = Irb.new(main, workspace, file) th = Thread.current Thread.start do #Thread.pass @Thread2Irb[Thread.current] = irb begin catch(:IRB_EXIT) do irb.run # <-- 子irbの立ちあげ end ensure @Thread2Irb[Thread.current] = nil if th.alive? # 親はいきているか? p th.stop? p Thread.critical th.run else @Thread2Irb.keys[0].run end end end print "zzzzzzzzz" Thread.stop end これを実行すると, 以下のようになります. dim% ruby irb.rb irb:001:0> irb irb#1:001:0> exit false false zzzzzzzzzirb.rb:252:deadlock 0x400fb7e4: 1:0 (main) で, デッドロックになってしまいます. 詳しく分析すると, 子スレッドが立ち 上がった後, 親スレッドに処理が回らなくて, Thread.stopに行かないためな のが分かります. 試しに, Thread.passを入れるとちゃんと動作します. また, irb#1:001:0> Thread.critical false irb#1:003:0> IRB.Thread2Irb.keys [#, #] irb#1:004:0> Thread.current # irb#1:005:0> IRB.Thread2Irb.keys[0].alive? true irb#1:006:0> IRB.Thread2Irb.keys[0].stop? false この結果のように, Thread.critical==falseです. こういうことって起こり得るんですかね? __ ..............................石塚 圭樹@日本ラショナルソフトウェア... ----------------------------------->> e-mail: keiju@rational.com <<---