質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.28%

  • C++

    2504questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

c++ Thread 例外発生時に止まる

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 91

Lopn_

score 30

C++でthreadを使用している際に、Thread内部でエラーが発生すると動作が停止してしまいます。

#include <thread>
#include <iostream>

void th (int n) {
 try {
  for () {
     /*処理*/
     /*これだと例外発生後にthreadが停止する??*/
  }
 }
 catch (AException &a) {
  /*エラー時の処理*/
 }
 catch (BException &b) {
  /*エラー時の処理*/
 }
 catch (CException &c) {
  /*エラー時の処理*/
 }
 catch (std::exception &e) {
  /*エラー時の処理*/
 }
 catch (...) {
  /*エラー時の処理*/
 }
}

int main () {
 try {
  std::thread thread1(th, 1);
  std::thread thread2(th, 2);
  std::thread thread3(th, 3);
  thread1.join();
  thread2.join();
  thread3.join();
 }
 catch (std::exception &e) {
  /*エラー時の処理*/
 }
 catch (...) {
  /*エラー時の処理*/
 }
}

AExceptionを意図的に発生させた際に、発生させたスレッドが停止してしまいます
どうすれば停止せずに続けられますか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

0

基本的にスレッドをまたいで例外が飛んでいくことはないと考えるべきです。
例えば以下のコードは強制終了します。

#include <thread>
#include <iostream>
#include <chrono>

struct AException {};

void th(int n) {
    for (int i = 0; i < 100; ++i) {
        try {
            std::cout << i << std::flush;
            if (i == n) {
                throw AException();
            }
            std::this_thread::sleep_for(std::chrono::seconds(1));
        } catch (const AException &a) {
            std::cout << "例外" << std::flush;
            throw a;
        }
    }
}

int main() {
    std::thread t;
    try {
        t = std::thread(th, 5);
        t.join();
    } catch (const AException &) {
        t.join();
        std::cout << "ここには来ない" << std::flush;
    }
}

それから勘違いだったらよいのですが、

AExceptionを意図的に発生させた際に、発生させたスレッドが停止してしまいます
どうすれば停止せずに続けられますか?

稀にgotoのつもりなのか例外を大量に発生させる人がいますが、そういうのはあまりよくないので例外を意図的に発生するのは控えめにしたようがよいかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/13 20:13

    これって
    try の中にfor文を挟むと例外発生以降はthreadが落ちてしまうんですね...
    私はtryの中にforを使って処理をいれていました..

    そのときのコードは質問を編集して載せてあります

    キャンセル

0

エクセプションを投げなければ正しく動作するのでしょうか。
th関数内のtryで投げれば正常に動作するように見えます。

Thread内部でエラーが発生すると動作が停止が、非同期処理が終了するという意味なら、正常な動作だと思います。
threadは非同期で一度だけ関数を実行します。
関数の処理を繰り返し実行したい場合はth関数の処理全てをwhileで囲ってください。

プロセス自体が異常終了するのであれば、そのエラー内容を書いてください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/13 13:46

    コード0で終了しているようなので異常終了ではないようです

    つまりは
    mainの中をwhileすればいいということですよね?

    キャンセル

  • 2018/01/13 18:09

    ↑実行を続けたいのが main なのか th なのかによる。

    キャンセル

  • 2018/01/13 19:09

    thの実行を繰り返したいです
    ログインの処理を入れてるのでできればリロードではなくエラーのパスをしたいです

    キャンセル

  • 2018/01/13 21:54

    ならば main を loop しても意味がない

    キャンセル

0

こんにちは。

main()関数でスレッド起動後、その実行や終了を待たずにmain()関数が終了しています。
この時点でプロセスが終了してしまいますので、各スレッドも強制終了されている筈です。
例えば、ここのサンプルのようなイメージでjoinを使ってスレッドの終了を待つ等の処理が必要と思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/13 19:10

    すみません、それはjoinの書き忘れです

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.28%

関連した質問

  • 解決済

    javaのclassをまとめたい

    質問内容 eclipseを使用してjavaのマルチスレッド(3つ)を作る課題をやっているんですが,現段階ではスレッドごとにクラスを作り処理を行っています。 最終的には一つのクラ

  • 解決済

    例外クラスとstd::exception

    C/C++でやっています。 C/C++で例外処理ってありますよね。 今までは int型で投げていたのですが、std::exception を継承すればより簡単にできるような

  • 解決済

    C++でJavaのcontainsAllを実現したい

    前提・実現したいこと C++のstd::setでJavaのcontainsAllを実現しようとしているのですが,イテレータの値を使ってset内を検索しようとすると以下のエラーが出ま

  • 解決済

    [c]一つのデータでカラム数が変わるデータの読み込み

    質問失礼します。プログラム初心者です。 以下のような〜〜〜.datを fp1 = fopen(fname1,"r"); while((ret = fscanf(fp1,"%d %d

  • 解決済

    C++での文字列のシャッフルについて

    こんにちは。 C++でFisher–Yatesシャッフルアルゴルズムを使って、複数の文字列をシャッフルできるようにしたいです。 そこでいろいろ調べてみましたが、C++でかつ複数の文

  • 解決済

    PHP 例外処理任意の例外検知

    例外処理についてです。 データベースなどを扱う際tryでデータベースの部分を囲みエラーを検知するなどの使い方があると思いますが、catchの部分で任意のエラーを検知する方法ってあり

  • 解決済

    std::mapの文字列キーを格納したstd::vectorをソートする

    前提・実現したいこと 文字列のキーと構造体の値を持つstd::mapとキーを格納したstd::vectorがあり、std::mapのキーに対応する値の1つのメンバ変数をもとにキーを

  • 解決済

    クラス間の変数の共有

    私はandroidstudioでアプリ開発を行っています。 Macからandroidへソケット通信を用いて下のコードにより獲得することができますがそのコードにあるString 

同じタグがついた質問を見る

  • C++

    2504questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。