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

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

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

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

Boost

Boost (ブースト)は、C++の先駆的な開発者のコミュニティ、 またそのコミュニティによって公開されているオープンソースライブラリのことを指します。

Q&A

解決済

2回答

3905閲覧

boost::threadを使ってみる

BeatStar

総合スコア4958

C++11

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

Boost

Boost (ブースト)は、C++の先駆的な開発者のコミュニティ、 またそのコミュニティによって公開されているオープンソースライブラリのことを指します。

0グッド

0クリップ

投稿2017/06/29 02:57

C/C++でやっています。

boost::thread をクラス化して使いやすくしようとしています。

サイトを参考にしながら自分なりにやってみました。

本当は TemplateMethodパターン適用で、

IThreadインターフェースクラス ( 自作 ) を定義してライブラリ化し、

使うときは

IThreadを継承して Mainメンバ関数を実装すればいい ( 他の独自のメンバ関数はオプションとして。 ) という風にしたいのですが、

調べても なかなかヒットしません。

[C++] スレッドからのコールバック│miscellaneous

のようにクラス化しているのもありますが、そのクラスのみで完結しています。
それ自体はいいですが、毎回boost::threadを手動で呼び出して...

としないといけないので...

探しながら考えてみると「関数オブジェクト」がありましたね。

クラスオブジェクトでありながら、operator() をオーバーロードしているので、関数のように使えるっていう。

なので、スレッド用クラスと スレッド操作クラスを別にしました。

[ CThreadManager ] + CONSTRUCTOR( func : boost::function<void (void)> ... ) + DESTRUCTOR() + Join( void ) : void [ throw(CExceptionEx) ] + Detach( void ) : void [ throw(CExceptionEx) ] ...

という風にboost::threadを( namespace THREAD = boost::thread のような感覚で) 簡単にしたような感じにしました。

( 上はあくまでイメージ )

CExceptionEx というのは std::exception を継承して生成した独自の例外クラスとします。

引数は

CExceptionEx( メッセージ, エラー番号 = -1 );

としています。

ソースコードの一部

( 字数制限のため )

リンク/インクルードともに出来ています。

方法1 ではうまくいくのですが、方法2 で試すと Th.Interrupt(); が無視されたような状態になります。

つまり、遅延生成をするとInterruptメンバ関数が無視状態。

どういう風にすればいいのでしょうか?

やはり、遅延は諦めるべきでしょうか?

[参考にしたサイト]

[情報]
言語 : C/C++
ライブラリ: Boost
コンパイラ: MinGW

宜しくお願い致します。

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

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

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

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

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

guest

回答2

0

CThreadManagerTest::Runの中で,m_bAlive = trueとする必要があるのではないでしょうか.
それをしないと,遅延評価ではm_bAliveがずっとfalseのままなので,CThreadManagerTest::Interrupt内の条件分岐で弾かれる気がします.

以下,該当部分だけ抜粋させていただきます.

c++

1// コンストラクタ1. 関数を引き受けて起動. bool bDelay が true なら遅延起動. 2CThreadManagerTest(boost::function<void (void)> func, int threadID = 1, bool bDelay = false) 3 : m_func(func), m_threadID(threadID), m_bDelay(bDelay) 4{ 5 if( !m_bDelay ){ 6 this->m_th = boost::thread( func ); 7 this->m_bAlive = true; 8 } else { 9 this->m_bAlive = false; // ここで false になる 10 } 11} 12 13// Runメンバ関数. 遅延起動時 効果あり. 14void Run(void) 15{ 16 if( this->m_bDelay && !this->m_func.empty() ){ 17 this->m_th = boost::thread( m_func ); 18 // ここで m_bAlive = true にしないといけない 19 } 20} 21 22// Interruptメンバ関数. 別スレッドに"終了"を指令. 別スレッドは InterruptPoint非メンバ関数でチェックする. 23void Interrupt(void) 24{ 25 // Run 内で m_bAlive を true にしていないので,m_th.interrupt() は実行されない 26 if( this->m_bAlive ) m_th.interrupt(); 27}

投稿2017/06/29 04:17

編集2017/06/29 04:24
tamy

総合スコア442

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

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

BeatStar

2017/07/01 04:10

ご回答ありがとうございます。 tamyさんの回答を読む前に他の方の回答( 古い方から ) から読んでしまいました。 ( スミマセン... 回答してくださったのに... ) 遅延起動をする Runメンバ関数内で m_bAlive を true にしていなかったために弾かれてスルー状態... 解決しました!
guest

0

ベストアンサー

こんにちは。

色々良く分からない部分が多いので、分かったところだけで回答してみます。外していたらごめんなさい。

方法2 で試すと Th.Interrupt(); が無視されたような状態になります。

方法2で起動しいるのは、コンストラクタ1と理解しました。(コメントミスですよね? 方法2では引数を3つ取るコンストラクタを起動していて、コンストラクタ1は引数3つ、コンストラクタ2は引数1つでしたので)

コスンラクタ1に渡しているbDelay引数はtrueですね。
これがtrueの時、m_bAliveメンバ変数はfalseです。
そして、Th.Interrupt()は、m_bAliveがfalseなら何もしません。
ということは、m_bAliveがfalseのままだと無視される動作になると思います。

コンストラクト後、m_bAliveをtrueにする部分を見つけることができませんでした。

因みに方法1もコンストラクタ1で起動してますが、bDelay引数はデフォルトのままですのでfalseです。従ってm_bAliveメンバ変数はtrueになるので、Th.Interrupt()はm_th.interrupt()を呼び出します。


【蛇足ですが①】
[ CThreadManager ]からの記述は何の構文でしょうか?
C++にはこのような構文はないと思います。
もしかして、マイクロソフトのオリジナルなC++/CLIではないでしょうか?
これはかなり強烈な機能拡張がされていますので、拡張部分を含まないプログラムを提示する時のみC++と呼ぶべきと思います。

【蛇足ですが②】
C++11でstd::threadが追加されました。
Visual Stduio 2012からstd::threadをサポートしているようです。
std::threadを使うことも検討されると良いように感じます。(必須ではないですが、その方が信頼性を上げやすいと思います。)

投稿2017/06/29 03:32

Chironian

総合スコア23272

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

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

BeatStar

2017/06/29 07:14

おおっと。 すみません。 方法2はコンストラクタ1 でした... 以前、boost::thread ではなく、std::thread ( C++11 ) をやってみましたが、 Win32版というのでしょうか、あれではサポートされていないようです。 蛇足1 ですが、 もしかして コード用で記した、[ CThreadManager ] とかの書き方でしょうか? すみません。 UMLぽく書いてわかりやすくした"つもり" だったんですが... m_bAliveの流れをですか... ああ! そういえば、true にするの忘れてた...
Chironian

2017/06/29 07:40

> 以前、boost::thread ではなく、std::thread ( C++11 ) をやってみましたが、Win32版というのでしょうか、あれではサポートされていないようです。 ああ、思い出しました。そう言えば以前回答させて頂いてました。 > UMLぽく書いてわかりやすくした"つもり" だったんですが... なるほどUMLでしたか。
BeatStar

2017/07/01 04:10

解決しました。 ご協力ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問