Basic timer with std::thread and std::chrono
c++, c++11, multithreading, timer
Solution
In `Timer::start`, you create a new thread in `th` and then immediately `join` it with `th.join()`. Effectively, `start` won't return until that spawned thread exits. Of course, it won't ever exit because nothing will set running to false until after `start` returns...
Don't `join` a thread until you intend to wait for it to finish. In this case, in `stop` after setting `running = false` is probably the correct place.
Also - although it's not incorrect - there's no need to make another thread in `main` to call `this_thread::sleep_for`. You can simply do so with the main thread:
int main()
{
Timer tHello;
tHello.start(chrono::milliseconds(1000), []{
cout << "Hello!" << endl;
});
this_thread::sleep_for(chrono::seconds(2));
tHello.stop();
}
Problem
I'm trying to implement a basic timer with the classic methods: start() and stop(). I'm using c++11 with std::thread and std::chrono. - Start method. Creates a new thread that is asleep for a given interval time, then execute a given std::function. This process is repeated while a 'running' flag is true. - Stop method. Just sets the 'running' flag to false. I created and started a Timer object that show "Hello!" every second, then with other thread I try to stop the timer but I can't. The Timer never stops. I think the problem is with th.join()[*] that stops execution until the thread has finished, but when I remove th.join() line obviously the program finishes before the timer start to count. So, my question is how to run a thread without stop other threads? ``` #include <iostream> #include <thread> #include <chrono> using namespace std; class Timer { thread th; bool running = false; public: typedef std::chrono::milliseconds Interval; typedef std::function<void(void)> Timeout; void start(const Interval &interval, const Timeout &timeout) { running = true; th = thread([=]() { while (running == true) { this_thread::sleep_for(interval); timeout(); } }); // [*] th.join(); } void stop() { running = false; } }; int main(void) { Timer tHello; tHello.start(chrono::milliseconds(1000), []() { cout << "Hello!" << endl; }); thread th([&]() { this_thread::sleep_for(chrono::seconds(2)); tHello.stop(); }); th.join(); return 0; } ``` Output: ``` Hello! Hello! ... ... ... Hello! ```