#include <iostream>
#include <chrono>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <atomic>
class Timer {
public:
enum class Mode {
SINGLE_SHOT,
PERIODIC
};
Timer() : m_expired(true), m_try_to_expire(false) {}
~Timer() {
stop();
}
void start(int interval, std::function<void()> task, Mode mode = Mode::PERIODIC) {
if (!m_expired.load()) return;
m_expired.store(false);
m_thread = std::thread([this, interval, task, mode]() {
std::unique_lock<std::mutex> lock(m_mutex);
while (!m_try_to_expire.load()) {
if (m_cv.wait_for(lock, std::chrono::milliseconds(interval),
[this] { return m_try_to_expire.load(); })) {
break;
}
task();
if (mode == Mode::SINGLE_SHOT) {
break;
}
}
m_expired.store(true);
m_try_to_expire.store(false);
});
}
void stop() {
if (m_expired.load() || m_try_to_expire.load()) {
return;
}
m_try_to_expire.store(true);
m_cv.notify_one();
if (m_thread.joinable()) {
m_thread.join();
}
}
private:
std::atomic<bool> m_expired;
std::atomic<bool> m_try_to_expire;
std::mutex m_mutex;
std::condition_variable m_cv;
std::thread m_thread;
};
int main() {
Timer timer;
// 单次定时器
timer.start(1000, [] {
std::cout << "Single shot timer triggered!" << std::endl;
}, Timer::Mode::SINGLE_SHOT);
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
// 周期定时器
timer.start(500, [] {
std::cout << "Periodic timer triggered!" << std::endl;
});
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
timer.stop();
return 0;
}