/*
* File: Timer
* Module: service
* Description:定时器类
* Author:
*/
#pragma once
#include<functional>
#include<chrono>
#include<thread>
#include<atomic>
#include<memory>
#include<mutex>
#include<condition_variable>
class Timer{
public:
Timer() :expired_(true), try_to_expire_(false){
}
Timer(const Timer& t){
expired_ = t.expired_.load();
try_to_expire_ = t.try_to_expire_.load();
}
~Timer(){
Expire();
}
void StartTimer(int interval, std::function<void()> task){
if (expired_ == false){
return;
}
expired_ = false;
std::thread([this, interval, task](){
while (!try_to_expire_){
std::this_thread::sleep_for(std::chrono::milliseconds(interval));
task();
}
{
std::lock_guard<std::mutex> locker(mutex_);
expired_ = true;
expired_cond_.notify_one();
}
}).detach();
}
void Expire(){
if (expired_){
return;
}
if (try_to_expire_){
return;
}
try_to_expire_ = true;
{
std::unique_lock<std::mutex> locker(mutex_);
expired_cond_.wait(locker, [this]{return expired_ == true; });
if (expired_ == true){
try_to_expire_ = false;
}
}
}
template<typename callable, class... arguments>
void SyncWait(int after, callable&& f, arguments&&... args){
std::function<typename std::result_of<callable(arguments...)>::type()> task
(std::bind(std::forward<callable>(f), std::forward<arguments>(args)...));
std::this_thread::sleep_for(std::chrono::milliseconds(after));
task();
}
template<typename callable, class... arguments>
void AsyncWait(int after, callable&& f, arguments&&... args){
std::function<typename std::result_of<callable(arguments...)>::type()> task
(std::bind(std::forward<callable>(f), std::forward<arguments>(args)...));
std::thread([after, task](){
std::this_thread::sleep_for(std::chrono::milliseconds(after));
task();
}).detach();
}
private:
std::atomic<bool> expired_;
std::atomic<bool> try_to_expire_;
std::mutex mutex_;
std::condition_variable expired_cond_;
};
2、简单版本的定时器执行任务
time.h
#include <condition_variable>
#include <functional>
#include <memory>
#include <mutex>
#include <thread>
class Time {
public:
Time();
~Time();
bool Init(size_t loop_interval_sec, const std::function<void(void)>& task);
private:
std::unique_ptr<std::thread> loop_thread_;
std::mutex loop_cv_mtx_;
std::condition_variable loop_cv_;
int loop_interval_sec_;
bool terminate_;
std::function<void(void)> task_;
};
time.hpp
#include "timed_task.h"
#include <chrono>
#include <iostream>
Time::Time()
: loop_thread_(nullptr)
, loop_interval_sec_(0)
, terminate_(false)
, task_(nullptr) {
}
Time::~Time() {
terminate_ = true;
loop_cv_.notify_all();
if (loop_thread_) {
loop_thread_->join();
}
}
bool Time::Init(size_t loop_interval_sec,
const std::function<void(void)>& task) {
if (loop_interval_sec == 0 || !task) {
return false;
}
loop_interval_sec_ = loop_interval_sec;
task_ = task;
loop_thread_.reset(new std::thread([this]() {
while (!terminate_) {
std::unique_lock<std::mutex> lck(loop_cv_mtx_);
loop_cv_.wait_for(lck, std::chrono::seconds(loop_interval_sec_));
std::cout << "execute timed task" << std::endl;
task_();
if (terminate_) {
break;
}
}
}));
return true;
}