4

Hi I am trying to find out the best peaceful way of terminating a worker thread. I have the following code:

class test{
  public:
test() {}
~test() {}

std::atomic<bool> worker_done;


int a;
void pr() {
    while (true) {
        if (worker_done) {
            break;
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        printf("%d \n", a++);
    }
}

std::thread* m_acqThread;
void continuous() {
    m_acqThread = new std::thread(&test::pr, this);
}

void stopThread(){
    if (m_acqThread) {
        if (m_acqThread->joinable())
            m_acqThread->join();
        delete m_acqThread;
        m_acqThread = nullptr;
    }
}


};


int main(){

test t;
t.continuous();

std::this_thread::sleep_for(std::chrono::milliseconds(2000));
t.worker_done = true;

t.stopThread();


std::string str;
std::cin.clear();
getline(std::cin, str);
return 0;

Is there a better way of notifying the worker's thread to be terminated other than setting "worker_done" to be true ?

Thanks

dbush
  • 162,826
  • 18
  • 167
  • 209
user1296153
  • 553
  • 5
  • 19

1 Answers1

2

What you have is fine: if you have a thread that say starts when your program opens, and as your program closes you need to stop it, using an atomic<bool> is the right way to do this.

It's possible to also use std::atomic_flag like so:

#include <thread>
#include <atomic>
#include <iostream>

std::atomic_flag lock;
int n = 0;

void t()
{
    while (lock.test_and_set())
    {
        ++n;
        std::this_thread::sleep_for(std::chrono::milliseconds(250));
    }
}

int main()
{
    lock.test_and_set();
    std::thread t(&t);
    std::this_thread::sleep_for(std::chrono::seconds(2));
    lock.clear();
    t.join();
    std::cout << n << std::endl;
    std::cin.get();
}

You can read about why you might wish to choose atomic_flag over atomic<bool>, but personally I prefer the use of atomic<bool> for things like this, as it's simply more readable:

std::atomic<bool> runThread;
int n = 0;

void t()
{
    while (runThread)
    {
        ++n;
        std::this_thread::sleep_for(std::chrono::milliseconds(250));
    }
}

int main()
{
    runThread = true;
    std::thread t(&t);
    std::this_thread::sleep_for(std::chrono::seconds(2));
    runThread = false;
    t.join();
    std::cout << n << std::endl;
    std::cin.get();
}
Tas
  • 6,589
  • 3
  • 31
  • 47
  • Would atomic_flag be better? – zzxyz Aug 17 '17 at 00:03
  • At least `atomic` is cheaper – LWimsey Aug 17 '17 at 00:53
  • 1
    Atomic Flag sounds like a forgotten 50's super hero. – user4581301 Aug 17 '17 at 00:56
  • 1
    ``atomic_flag`` does not have a test operation, only ``test_and_set`` and ``clear``. Signalling another thread is unnecessarily difficult with these primitives. The only advantage is that it is defined by the standard to be lock-free rather than implementation-defined. But ``atomic`` is lock-free on all major implementations. (Didn't notice that Tas already discussed ``atomic_flag``.) – Arne Vogel Aug 17 '17 at 13:53