#include <future>
#include <chrono>
#include <thread>
#include <iostream>
using namespace std::chrono_literals;
int main()
{
bool keep_running{ true }; // a flag indicating if you want to keep processing
std::condition_variable signal; // a signal between two threads that (maybe) keep_running has changed value
std::mutex mtx; // a mutex to use with flag/signal. (mutexes are often needed when more then 1 thread is involved)
std::cout << "press return to stop\n";
char output_char = 'x';
// launch a lambda function in a thread
// pass the boolean keep running
// [&] captures : output_char, mtx, signal and keep_running by reference
// making them available in the background thread.
// (Make sure these variables 'live' longer then the duration of the thread
// thats why the future.get() later is important).
auto future = std::async(std::launch::async, [&]
{
while (keep_running)
{
std::cout << output_char << std::flush; // show we are looping
// get a lock, this is needed for safe waiting on the signal
std::unique_lock<std::mutex> lock{ mtx };
// I tend to never use sleep, but use a condition variable to
// be able to respond faster
// wait_for waits for 5s OR until keep_runnning is false
signal.wait_for(lock, 1s, [&] { return !keep_running; });
}
});
auto c = getchar();
std::cout << "stopping\n";
// update keep_running and condition variable in a lock too
{
std::unique_lock<std::mutex> lock{ mtx };
keep_running = false;
signal.notify_one();
}
future.get(); // wait for thread to have stopped.
std::cout << "stopped\n";
return 0;
}