我的主线程正在进行更长的计算。在那段时间应该运行第二个线程(一种计算监视/统计)。一旦计算完成,它应该停止监视线程。使用了使用共享标志变量的经典方法(c.f. How to stop a running thread safely on user request?)。
#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
这是怎么回事?提前感谢您的回答!
最佳答案
David,感谢您提供的所有有用提示。如果您只需要坚持使用 tbb,那么引用共享数据的 Foo 构造函数就可以了。我使用 Boost 找到了一个更独立的解决方案。我的实际意图是这样的:
#include <iostream>
#include "boost/ref.hpp"
#include "boost/thread.hpp"
#include "tbb/atomic.h"
using namespace std;
using namespace tbb;
class Foo : public boost::thread {
atomic<bool> _stop;
public:
Foo();
Foo(const Foo& rhs);
void operator()();
void stop();
};
Foo::Foo() : thread(ref(*this)) {
cout << "Foo::Foo() called: " << this << endl;
_stop = false;
}
Foo::Foo(const Foo& rhs) {
cout << "Foo::Foo(const Foo&) called: " << this << endl;
_stop = rhs._stop;
}
void Foo::stop() {
_stop = true;
cout << "Foo:stop() set _stop=" << _stop << endl;
cout << "Foo:stop() calling interrupt()" << endl;
interrupt();
cout << "Foo:stop() calling join()" << endl;
join();
cout << "Foo:stop() joined" << endl;
}
void Foo::operator()() {
int i = 0;
while (!_stop) {
cout << " Foo::operator() still alive " << i << " (" << this << ")" << endl;
if (_stop) {
cout << " Foo::operator() is asked to finish" << " (" << this << ")" << endl;
break;
}
boost::this_thread::sleep( boost::posix_time::seconds(20) );
++i;
}
}
int main() {
Foo foo;
cout << "starting longer calculation" << endl;
int sum;
for (int i = 0; i < 3; ++i) {
sum += i;
sleep(1);
}
cout << "finished longer calculation" << endl;
foo.stop();
return 0;
}
这导致
Foo::Foo() called: 0x7fff6c7b9ff0
starting longer calculation
Foo::operator() still alive 0 (0x7fff6c7b9ff0)
finished longer calculation
Foo:stop() set _stop=1
Foo:stop() calling interrupt()
Foo:stop() calling join()
Foo:stop() joined
关于c++ - 根据用户请求停止 tbb 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12251778/