1

Does anybody know why this program goes into an infinite loop, instead of stopping after 5s or so?

This happens with both the latest gcc and clang compiler; does atomic_bool suffer from hte same issues as a vector of bool?

If I use atomic<int> this works fine.

#include <algorithm>
#include <memory>
#include <utility>
#include <iostream>
#include <vector>
#include <functional>
#include <future>
#include <chrono>


using namespace std;
using namespace chrono_literals;

void send_heart_beat()
{
    cout << "sending heartbeat" << endl;
}

std::future<void> f;
int main()
{
   std::atomic<bool> stop(false);
   f = std::async(std::launch::async,[&stop]() { while(!stop) { send_heart_beat(); std::this_thread::sleep_for(1s); } });
   std::this_thread::sleep_for(5s);
   stop = true;
}
Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
user8063157
  • 285
  • 1
  • 13

1 Answers1

3
 std::atomic<bool> stop(false);
 std::future<void> f;

These two variables are in different scopes, and f's scope is longer lived than stop's scope.

f = std::async(std::launch::async,[&stop]() { while(!stop) { send_heart_beat(); std::this_thread::sleep_for(1s); } });

here we bind a reference to stop into a lambda, and then store a (copy) of that lambda into an async object which is managed by f.

When f goes out of scope, its destructor waits for the async task to finish. But because f's scope is longer lasting than stop's, we leave the scope of stop before f waits for the thread to finish.

So our thread mindlessly continues accessing stop after stop no longer exists through a dangling reference.

This results in undefined behavior; any behavior by your program is acceptable to the standard.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524