From: keiju@... (=?ISO-2022-JP?B?GyRCQFBETTc9PHkbKEI=?= ) Date: 1997-08-18T12:33:49+09:00 Subject: [ruby-dev:153] Re: thread debug[Re: tracer] けいじゅ@日本ラショナルです. In [ruby-dev :00152 ] the message: "[ruby-dev:152] Re: thread debug[Re: tracer] ", on Aug/18 09:36(JST) matz@netlab.co.jp (Yukihiro Matsumoto) writes: >まつもと ゆきひろです >|それよか, exitの代わりに abort 見たいな関数を用意して頂けると良いかも: >それはよいかも.用意しましょう. お願いします(__; >|>全体を停止するんですか.有効なのかしら? >|原因となったスレッドのバックトレースを出してもらえるなら, 有効だと思う >|んですが... 有効じゃないと思われる深い理由があるのかしら? >スレッドって他のスレッドとの相互作用で動作しますからね.エラー >が起きた場所だけじゃ不十分かなって思ったんですけど,まあ,わ >からないよりはましかも知れませんね. そういう複雑な問題も当然あるんですけども, 良くやる間違いはパラメータの 数があっていないとか, 関数名が間違っているとか, そういうたわいもないも のが多いので, あると非常に嬉しいです. >| set_trace_func見たいな仕様です. カレントスレッドに足して設定し, その >|後, そのスレッドからフォークした小スレッドにも引き継がれる. >|3. Thread.join関係 >|現在のThread.joinはスレッドを指定しなくてはなりませんよね. >| >|* Thread.wait >| Process.wait見たいな機能で任意の(子)スレッドが終了するまで待つ. >| >|* Thrad.join thread,... >| >| 待つスレッドを複数指定できるメソッド >| >|でも, Thread.waitみたいのは難しいのかな? 親/小スレッドっていう概念がな >|いですものね? > >子スレッドがないので,Thread.waitは無理でしょうね.子どもで >もない任意のスレッドが終了したのを教えてもらっても嬉しくない >でしょうし. それはそうですね. 了解しました. >あと,モデルが複雑になるのを避けたいので,複数スレッドに対し >て待つというのも採用したくないですねえ. そうなんですか?? そんなに複雑になるんですか... そういう機能を追加する とそれに関した機能追加が必要になるという意味ではそうかも知れませんね (後述参照). >スレッドは軽い(はず)なので,待ちたいスレッドに対してjoinする >スレッドを用意して,Queueで待つというのはどうでしょう. > > > thread thread > | | > thread.join thread.join > | | > ---Queue--- > | > thread > >って感じですけど. おお. なるほど!! 早速クラスライブラリを作りました. # やはり, joinだけでなくいろいろな機能が必要になりました. クラス名はThreadsWaitです. 使い方はソース中のドキュメントを見れば分か ると思いますが, 基本的な使い方は: [1] tw = ThreadsWait.new th1 = tw.join(th,...) th2 = tw.next_wait : [2] tw = ThreadsWait.new(th, ..) th1 = tw.next_wait : [3] ThreadsWait.all_waits do |th| ... end などです. よければ, contribにおいて下さい. --ここから. # # threads-wait.rb - # $Release Version: $ # $Revision: 1.1 $ # $Date: 1997/08/18 03:13:14 $ # by Keiju ISHITSUKA(Nippon Rational Inc.) # # -- # # # require "thread.rb" require "e2mmap.rb" class ThreadsWait RCS_ID='-$Header: /home/keiju/var/src/var.lib/ruby/RCS/threads-wait.rb,v 1.1 1997/08/18 03:13:14 keiju Exp keiju $-' Exception2MessageMapper.extend_to(binding) def_exception("ErrWaitThreadsNothing", "Wait threads nothing.") def_exception("FinshedThreadsNothing", "finished thread nothing.") # class mthods # all_waits # # 指定したスレッドが全て終了するまで待つ. イテレータとして呼ばれると # 指定したスレッドが終了するとイテレータを呼び出す. # def ThreadsWait.all_waits(*threads) tw = ThreadsWait.new(th1, th2, th3, th4, th5) if iterator? tw.all_waits do |th| yield th end else tw.all_waits end end # initialize and terminating: # initialize # # 初期化. 待つスレッドの指定ができる. # def initialize(*threads) @threads = [] @wait_queue = Queue.new join_nowait(*threads) unless threads.empty? end # accessing # threads # 待ちスレッドの一覧を返す. attr :threads # testing # empty? # finished? # # # 待ちスレッドが存在するかどうかを返す. def empty? @threads.empty? end # # すでに終了したスレッドがあるかどうか返す def finished? !@wait_queue.empty? end # main process: # join # join_nowait # next_wait # all_wait # # 待っているスレッドを追加し待ちにはいる. # def join(*threads) join_nowait(*threads) next_wait end # # 待っているスレッドを追加する. 待ちには入らない. # def join_nowait(*threads) @threads.concat threads for th in threads Thread.start do th = Thread.join(th) @wait_queue.push th end end end # # 次の待ちにはいる. # 待つべきスレッドがなければ, 例外ErrWaitThreadsNothing を返す. # nonnlockが真の時には, nonblockingで調べる. 存在しなければ, 例外 # FinishedThreadNothingを返す. # def next_wait(nonblock = nil) Threads.Wait.fail ErrWaitThreadsNothing if @threads.empty? th = @wait_queue.pop(nonblock) @threads.delete th th end # # 全てのスレッドが終了するまで待つ. イテレータとして呼ばれた時は, ス # レッドが終了する度に, イテレータを呼び出す. # def all_waits until @threads.empty? th = next_wait yield th if iterator? end end end -- ここまで __ ..........................................石塚 圭樹@日本ラショナル... ----------------------------------->> e-mail: keiju@bc.mbn.or.jp <<---