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;
}
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.