私のメインスレッドはより長い計算を行っています。その間、2番目のスレッドを実行する必要があります(一種の計算監視/統計)。計算が終了すると、監視スレッドを停止する必要があります。共有フラグ変数を使用する従来のアプローチが使用されます(ユーザーの要求に応じて実行中のスレッドを安全に停止する方法を参照)。
#include <iostream>
#include "tbb/compat/thread"
#include "tbb/atomic.h"
#include "tbb/spin_mutex.h"
using namespace tbb;
using namespace std;
class Foo {
bool _stop;
spin_mutex _stopMutex;
public:
Foo();
void operator()();
bool stop();
void stop(bool);
};
Foo::Foo() {
_stop = false;
}
bool Foo::stop() {
spin_mutex::scoped_lock lock(_stopMutex);
return _stop;
}
void Foo::stop(bool stop) {
spin_mutex::scoped_lock lock(_stopMutex);
_stop = stop;
cout << "Foo::stop(bool) new value: " << _stop << endl;
}
void Foo::operator ()() {
int i = 0;
while (true) {
cout << " Foo::operator() still alive " << i << endl;
{
spin_mutex::scoped_lock lock(_stopMutex);
if (_stop) {
cout << " Foo::operator() is asked to finish" << endl;
break;
}
}
if (i > 15) {
spin_mutex::scoped_lock lock(_stopMutex);
_stop = true;;
}
sleep(1);
++i;
}
}
int main() {
Foo foo;
thread fooThread(foo);
cout << "starting longer calculation" << endl;
int sum;
for (int i = 0; i < 3; ++i) {
sum += i;
sleep(1);
}
cout << "finished longer calculation" << endl;
for (int i = 0; i < 5; ++i) {
foo.stop(true);
cout << "main() stop=" << foo.stop() << endl;
sleep(1);
}
cout << "main() calling join()" << endl;
fooThread.join();
cout << "main() fooThread joined" << endl;
return 0;
}
ただし、共有変数はスレッド間で共有されません。各スレッドには独自のインスタンスがあるようです。監視スレッドは、それ自体が停止するまで停止しません。出力を見てください:
starting longer calculation
Foo::operator() still alive 0
Foo::operator() still alive 1
Foo::operator() still alive 2
finished longer calculation
Foo::stop(bool) new value: 1
main() stop=1
Foo::operator() still alive 3
Foo::stop(bool) new value: 1
main() stop=1
Foo::operator() still alive 4
Foo::operator() still alive 5
Foo::stop(bool) new value: 1
main() stop=1
Foo::operator() still alive 6
Foo::stop(bool) new value: 1
main() stop=1
Foo::operator() still alive 7
Foo::stop(bool) new value: 1
main() stop=1
Foo::operator() still alive 8
main() calling join()
Foo::operator() still alive 9
Foo::operator() still alive 10
Foo::operator() still alive 11
Foo::operator() still alive 12
Foo::operator() still alive 13
Foo::operator() still alive 14
Foo::operator() still alive 15
Foo::operator() still alive 16
Foo::operator() still alive 17
Foo::operator() is asked to finish
main() fooThread joined
ここで何が起こっているのですか?よろしくお願いします!