• ベストアンサー

マルチスレッド:スレッドの終了を検知する(Ruby)

2つ以上のスレッドを生成・動作させ、それらが終了した時点で、メインに処理を移すといったことをRubyでしたいと思っています。 (スレッドが1つならば、メインをstopさせておき、スレッドの終了時に例外処理などを使ってrunさせる方法は思いつくのですが。。) 一つ考えたのは・・・ カウンタ変数をつくり、一つのスレッドが終了したらその値を増やす。 メインではwhileループによってその値を常に数えて、全スレッドの終了を把握する。 ただ無駄にwhileループを回してしまいます。。 一般的な効率の良い手段等あるのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.2

joinメソッドでスレッドの終了を待つことができます。 参考URLを参照下さい。

参考URL:
http://www.namaraii.com/rubytips/?%A5%B9%A5%EC%A5%C3%A5%C9
skip_jack
質問者

お礼

スレッドt1 スレッドt2 t1.join t2.join main処理 という流れで処理できました。 こんなに簡単な方法があったんですね。 基本的なところでした。 解答ありがとうございました。

その他の回答 (1)

  • tetsumyi
  • ベストアンサー率26% (1857/7093)
回答No.1

スレッドが終了した時点で メインに処理を移すのであればマルチスレッドにする必要は無いと思うのですが?

skip_jack
質問者

補足

各フェーズの処理に時間がかかり、しかしシステムのリソースがあまっているため、同時に実行させたいと思っていました。

関連するQ&A

  • マルチスレッド内のループについて

    こんにちは。 開発環境は VC++6.0 SDI マルチスレッドがあり、2つの処理を行う関数が書かれています。 このスレッドはダイアログボックスに配置したストップボタンを押すとフラグFALSEになりループを終了させます。 2つの関数は、int型の整数を引数にして、処理を行います。 整数はある値に達すると 0 になり永遠にループを続け、2つの処理を行います。 と言う意味合いでプログラムを書きました。(書いたつもりです) (1)この書き方ですと、for内のループが動いている時に、右上の×ボタンでダイアログを閉じると [Debug Assertion Failed!]と言う警告文が出て強制的に終了してしまいます。 ストップボタンを押してもcount=10になるまではループしています。(当然ですが・・。) そもそもマルチスレッドの中にこのような形でfor文を入れるのは間違っているのでしょうか? どのような書き方にすれば良いのでしょうか? よろしくお願い致します。 bool m_flags;//スレッド内の処理を続けるか示すフラグ UINT CabcDlg::thread(LPVOID pParam)// { CabcDlg *pInst = (CabcDlg *) pParam; while(pInst->m_flags){//ストップボタンが押されると終了する。 for (int count = 0; count<10; count++ ) { pInst->OnSend(count); //処理A pInst->OnReceive(count);//処理B } } return 0; }

  • スレッドについて

    スレッドについて勉強中なのですが、簡単なスレッド作り、 スレッドの処理が終わってからメインの処理を行わせたくて 以下のようなプログラムを書いてみました。 そこで、WaitForSingleObjectを使ってスレッドが終了するのを 待ちたいのですが、WaitForSingleObjectではまってしまうようで sprintfのメッセージ(スレッドが止まってしまっている)が 表示されません。 WRITE関数の処理が終われば、、WaitForSingleObjectで処理が 戻ってくると考えているのですが…。 スレッドについてと、間違いについて教えてもらえないでしょうか? 宜しくお願いします。 main { if(!stop) {   File = CreateFile(...); g_hThead = CreateThread(NULL,0,WRITE,(LPVOID)NULL,0,NULL); g_stop = false; }else { g_stop = true; ::WaitForSingleObject(g_hThead, INFINITE); CloseHandle(File); CloseHandle(hThead ); } } void WRITE() { while(!g_stop) { WriteFile(...); } ...処理を行う sprintf("スレッドを終了します。") }

  • スレッドの安全な終了のさせ方

    スレッドの安全な終了のさせ方  メインスレッドにてCreateThread命令を使い、あるサブスレッドを作りました。 このサブスレッドは内部でmallocを使い動的に配列領域を確保して その配列領域をforループ等で「かなり時間の掛かる処理」として繰り返し アクセスしています。 ループが終了した時に「free」を実行してmalloc領域を開放しています。 アプリ終了時にメインスレッドからこのサブスレッドを終了させるのに メインウインドウにWM_DESTROYメッセージが送られた時、これまで単に そこで「CloseHandle(hSubThread);」とだけ書いていたのですが、 もしかしたらこれでは場合によっては(サブスレッドがループ処理中だったら) malloc領域が開放されずにリークしてしまうのではないかと思いました。  そこでイベントオブジェクトを使い、サブスレッドがループ処理中の 時には非シグナル状態にして、ループが終了しfreeで領域を開放した後 シグナル状態にするということにして、メインスレッドはそれを WaitForSingleObjectで待つという構造にしました。 ところが「メインスレッドに待ちを作るな」という言葉通り、これでは 上手く行きませんでした。サブスレッドはその時間の掛かる処理の 最中でSendMassage等でメインスレッドの処理を促すような命令を (例えばその処理の進捗状況を表示するなど)を幾つも行っていたので、 もしWaitFor~でメインを待たせると「サブスレッドの処理も進まなくなり 結果両方がロックして動かなくなってしまう」という悲しい状況に 嵌ってしまうのです。 SendMessageを徹底的に無くすということも考えたのですが、 (例えばPostMessageに書き換えるなどもやってみたのですが、これは 全く意図した動作をしてくれない場合もあり)、別の方法では どうしても代替できないケースもあって、全て消すというのは 現実的ではないのかもと。。  このようなサブスレッドを安全に終了させるにはどうしたら良いでしょうか? あるいは単にデストロイ時にCloseHandleとするだけでも良いのでしょうか?

  • Threadの終了

    http://sdc.sun.co.jp/java/docs/j2se/1.4/ja/docs/ja/api/index.html を見ると,スレッドの止め方が書いてありますが, これは,スレッドblinker内でループが回っていて初めてうまく行く, と(間違ってるかもしれませんが)理解しています. では下記のように,Thread2でループが回っていない場合は (*)の位置でThread2を止めるにはどうすればいいのか, 教えてくださる方はいらっしゃいませんでしょうか. (**)のClassAではSWTでGUIを表示させていて, それをThread1から閉じるというのが目的です. GUIを閉じない限りその先には進まないので, ループを回しThread2のrun()内で待機させることが出来なくて. public class Thread1 { Thread1(){ Thread2 t2 = new Thread2(); t2.start(); try { Thread.sleep(5000); } catch (InterruptedException e) { } (*)ここでThread2を終了させたい. } public static void main(String args[]){ new Thread1(); } class Thread2 extends Thread { public void run() { new ClassA(); ・・・(**) } } }

    • ベストアンサー
    • Java
  • スレッド

    Thread th; //スレッド変数th宣言 public void start() {th = new Thread(); th.start();} //スレッドの開始 run(){Thread me = Thread.currentThread();      while(th == me){動作変数の処理} paint(){画像表示} 以上のような処理なのですが、 よく意味がわかりません。 特にwhile文の部分です。 currentThread とは?と聴いたところ 「現在実行中のスレッド」 だと言われました。 変数meに現在動作中のスレッドを代入する。 ??よく事情がわからないのです。 このプログラムはdrawOvalで丸を描いて、それを移動させると言うものなのですが、スレッドは2つ動いてると言うのです。動作変数処理と表示処理の2つだそうです。 で、meが動作、thが表示だと言うのですが正しいですか?まず通常動作するスレッドとth.start()で動くスレッドで、2つということはわかります。 で、現在実行中のスレッドと実行させたスレッドが等しい(trueまたはfalse)だと言うことが何を意味しているのか・・・????なのです・・・ これはどういうことなのでしょうか?? 質問してもまだ良くわからなそうなかおをしていたところ 「2つの処理を同時に処理するためと覚えてください」 と切り捨てられてしまいました。 これは正しいでしょうか・・・? 記述の足りない部分は補足いたします。 ご指摘お願いします。

    • ベストアンサー
    • Java
  • c# スレッド間でのデータの共有

    C#でメインプロセスと生成されたスレッド間でデータの共有をさせたいのですがどのようにすればいいのでしょうか。ご教授お願い致します。 ・メインプロセス(A) ・Aから生成されたスレッド(B) 例えば、AとBで変数の値をそれぞれ読み書きさせたい場合 どのようにすればよいのでしょうか。 class TEST { public int flag; // メインプロセス(A) public static void Main() { Thread t = new Thread(new ThreadStart(abc)); t.IsBackground = true; t.Start(); while(ture) { Thread.Sleep(10); Console.WriteLine("A:{0}",flag); } } // Aから生成されたスレッド(B) public void abc() { Console.WriteLine("B:{0}",flag); flag++; } }

  • スレッド中でウインドウのイベント(Windows)

    カテゴリー違いかもしれませんが、 Windowsでスレッド中でウインドウを生成すると、 イベントの処理ができなくなります。 (たぶんもとのイベントループにメッセージがいって  そこで終わっていると思うのですが) これを避ける方法とかあるのでしょうか? メインループにメッセージを送ってそこでウインドウを 生成してもらうのが由緒正しい方法なのでしょうか? 用語とかむちゃくちゃかもしれませんが よろしくお願いします。

  • VC++スレッドの正しい終了のさせかた

    VC++6.0にてAfxBeginThreadで m_bAutoDelete = TRUEにてスレッドをおこしております。 この終了時に制御関数のwhileループを脱する様にし、 正常にスレッドを終了させているつもりです。 この後、再度(アプリは継続して起動したまま) AfxBeginThreadにて全く同じ処理で再開すると、 なぜか、前のスレッドが未だ動作しているかのごとく 制御関数内のTRACEが2重に出力されます。 再度、停止し、またスレッド起動すると、 今度は3重になったかの様な動作をします。 スレッドが正しく終了されていないのでは?と思った現象として、 1回起動時にアプリを終了させると正常終了しますが、 2回起動以上は必ずスレッドのメモリーリークが出ます。 メモリーリーク個所はAfxBeginThreadでした。 制御関数内で必要ないとは思いましたが、終了時に AfxEndThreadを使用しましたが現象は同じでした。 そこで質問です。 1)この現象は、スレッドが正常に終了されていない事に起因しているのでしょうか? 2)スレッドを正しく終了させるにはどうすればいいのでしょうか? 当方、制御関数がループを抜け、さらにm_bAutoDelete = TRUEであれば オブジェクトも自動的に破棄されると思っていたのですが。。。 以上、よろしくお願いします。

  • 【Ruby】マルチスレッドでなくマルチプロセスで

    以下の様なプログラムをマルチスレッドでなくマルチプロセスで実現したいです。 #!/usr/bin/ruby require 'thread' q=Queue.new data=%w(a * * * b * * c * * d * *) data.each do |d| q.push d end (1..4).each do |n| Thread.start { while 1 do d=q.shift break if d!='*' end puts n.to_s+' '+d.to_s }.join end rubyのバーションは ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin10.0] です。バージョンをあげる事は、できれば避けたいです。 実際には上記プログラムの【puts n.to_s+' '+d.to_s】してる所は、ネットに繋いで云々の時間のかかる処理なのですが、まったくパラレルに行なっている様子が無いので、マルチプロセス化したら早くなるかなと思いました。 子プロセスを生成して親プロセスとはパイプで繋いで、、などとするのかなあと試行錯誤したのですが、どうもうまくできません。 ご指導の程、よろしくお願い申し上げます。

    • ベストアンサー
    • Ruby
  • java のスレッドについて

    java のスレッドについて javaでスレッドを作って処理をさせたいと思います。 メインのクラスでスレッドAを呼び出し、スレッドAで計算をしてその結果をメインのクラスで利用したい場合、一番簡単な方法は何でしょうか? なお、メインのクラスは、 while (Thread.isAlive()); な感じでスレッドが終わるまで処理を止めておきたいと思います。 簡単なコードを書いていただけないでしょうか?

    • ベストアンサー
    • Java

専門家に質問してみよう