[英]stop tbb thread 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
這里發生了什么? 預先感謝您的答復!
大衛,謝謝您提供的所有有用提示。 如果只需要堅持使用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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.