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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

Q&A

解決済

2回答

11016閲覧

std::thread の子スレッドが親より後に終了した際のエラー回避について

kobaya_c

総合スコア30

C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

0グッド

0クリップ

投稿2016/04/14 09:30

編集2016/04/14 09:31

スレッド(以下:親)からスレッド(以下:子)を作成した時、子が終了した時すでに親が終了している場合、ライブラリ内部で abort() を呼ばれてしまうため、対処方法を模索しております。

C++

1#include <stdio.h> 2#include <thread> 3 4void ThreadA(void* data){ 5 printf("%c", ((char*)data)[0]); 6 return; // これは大丈夫 7} 8 9void ThreadChild(void* data){ 10 printf("%c", ((char*)data)[0]); 11 return; // この後にエラー 12} 13 14void ThreadB(void* data){ 15 std::thread tC(ThreadChild, data); // スレッド内部でスレッドを作成する 16 //tC.join(); 17 return; 18} 19 20int main(){ 21 22 char a, b; 23 a = 'A'; 24 b = 'B'; 25 26 std::thread tA(ThreadA, &a); 27 std::thread tB(ThreadB, &b); 28 29 tA.join(); 30 tB.join(); 31 32 getchar(); 33 return 0; 34}

うまくいけば、AB と表示された後入力待ちになりますが、上記のままですと、『return; // この後にエラー』の行の後で異常終了してしまいます。

子の終了を先に待つように 『//tC.join();』のコメントアウトを解除すると問題がないのですが、実践的な処理としては、親の状態にかかわりなく子を無事に完了させたいと考えております。

親子関係かかわりなく個別にスレッドを終了する方法はありますでしょうか?
よろしくお願いします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

アボートしているのはThreadChild関数ではなく、ThreadB関数の方です。threadクラスは、joinまたはdetachしないままデストラクタが呼ばれると、アボートする仕様となっています。

何らかの方法でThreadB関数で作成したthreadオブジェクトをmain関数に引き渡してjoinさせる必要があります。

threadクラスはムーブが可能なので、main関数で空のtCオブジェクトを作成し、out引数としてThreadBに渡すという方法が考えられます。

投稿2016/04/14 10:47

catsforepaw

総合スコア5938

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kobaya_c

2016/04/15 01:07

ありがとうございます。もし他の方法でうまくいかなかった場合、別口に管理構造を作り確保させる、ということも視野に入れたいと思います。
guest

0

ベストアンサー

kobaya_cさんのやりたいことが完全に理解できていませんが、
tC.join(); を tC.detach(); にすれば、ThreadBはブロックされません。
cpprefjp std::thread

投稿2016/04/14 10:26

JADEN

総合スコア106

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kobaya_c

2016/04/14 10:41

ありがとうございます! detach() を使用することで、親子関係にあっても並列処理のようにできました。
catsforepaw

2016/04/14 10:49

念のため補足しておきます。detachすると子スレッドの「完了」は保証できなくなりますのでご注意を。
JADEN

2016/04/14 11:08

>> 親の状態にかかわりなく子を無事に完了させたいと考えております。 とあるので、確かにまずいですね。 下で回答されている方法以外では、std::promise<void>を使ってもできそうですね。
kobaya_c

2016/04/15 00:58

catsforepaw さん、ありがとうございます。今回のテストコードではすぐ終わるので表面化しませんでしたが、完了が把握できなくなるのは後々困りそうですね。 JADEN さん、違う関数のご紹介ありがとうございます。こちらの方の機能も確認してみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問