Nelson P Nelson P - 9 months ago 41
C++ Question

Approach of using an std::atomic compared to std::condition_variable wrt pausing & resuming an std::thread in C++

This is a separate question but related to the previous question I asked here

I am using an

in my
code to constantly poll for some data & add it to a buffer. I use a
C++ lambda
to start the thread like this:

StartMyThread() {

thread_running = true;
the_thread = std::thread { [this] {
while(thread_running) {

is an
declared in class header. Here is my

GetData() {
//Some heavy logic

Next I also have a
function where I set
to false so that it exits out of the while loop in the
lambda block

StopMyThread() {
thread_running = false;

As I understand, I can pause & resume the thread using a
as pointed out here in my earlier question.

But is there a disadvantage if I just use the
to execute or not execute the logic in
like below ?

GetData() {
if (thread_running == false)
//Some heavy logic

Will this burn more CPU cycles compared to the approach of using an
as described
here ?

Answer Source

There's two different problems being solved and it may depend on what you're actually doing. One problem is "I want my thread to run until I tell it to stop." The other seems to be a case of "I have a producer/consumer pair and want to be able to notify the consumer when data is ready." The thread_running and join method works well for the first of those. The second you may want to use a mutex and condition because you're doing more than just using the state to trigger work. Suppose you have a vector<Work>. You guard that with the mutex, so the condition becomes [&work] (){ return !work.empty(); } or something similar. When the wait returns, you hold the mutex so you can take things out of work and do them. When you're done, you go back to wait, releasing the mutex so the producer can add things to the queue.

You may want to combine these techniques. Have a "done processing" atomic that all of your threads periodically check to know when to exit so that you can join them. Use the condition to cover the case of data delivery between threads.