簡體   English   中英

根據用戶要求停止tbb線程

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM