1.Timer.h
#ifndef _TIMER_H_
#define _TIMER_H_
#include <iostream>
#include <thread>
#include <atomic>
#include <mutex>
#include <chrono>
#include <condition_variable>
#include <functional>
class Timer {
public:
Timer();
Timer(const Timer &t);
~Timer();
void StartTimer(int interval, std::function<void()> task);
void Expire();
void SyncWait(int after, std::function<void()> task);
void AsyncWait(int after, std::function<void()> task);
private:
std::atomic<bool> expired_;
std::atomic<bool> try_to_expire_;
std::mutex mutex_;
std::condition_variable expired_cond_;
};
#endif
2.Timer.cpp
#include "Timer.h"
using namespace std;
Timer::Timer() : expired_(true), try_to_expire_(false)
{
}
Timer::Timer(const Timer &t)
{
expired_ = t.expired_.load();
try_to_expire_ = t.try_to_expire_.load();
}
Timer::~Timer()
{
Expire();
}
void Timer::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 Timer::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;
}
}
void Timer::SyncWait(int after, std::function<void()> task)
{
this_thread::sleep_for(chrono::milliseconds(after));
task();
}
void Timer::AsyncWait(int after, std::function<void()> task)
{
thread([after, task](){
std::this_thread::sleep_for(chrono::milliseconds(after));
task();
}).detach();
}
3.test.cpp
#include "Timer.h"
using namespace std;
void EchoFunction(string &&s)
{
cout << "test: " << s << endl;
}
int main()
{
Timer t;
/*周期性执行定时任务*/
t.StartTimer(1000, bind(EchoFunction, "hello world!"));
this_thread::sleep_for(chrono::seconds(4));
t.Expire();
cout << "try to expire timer!" << endl;
/*周期性执行定时任务*/
t.StartTimer(1000, bind(EchoFunction, "hello c++11!"));
this_thread::sleep_for(chrono::seconds(3));
cout << "try to expire timer!" << endl;
this_thread::sleep_for(chrono::seconds(1));
t.Expire();
/*只执行一次定时任务*/
/*同步执行*/
t.SyncWait(1000, bind(EchoFunction, "hello world!"));
/*异步执行*/
t.AsyncWait(1000, bind(EchoFunction, "hello c++!"));
this_thread::sleep_for(chrono::seconds(2));
return 0;
}
4.编译源码
$ g++ -o test test.cpp Timer.cpp -std=c++11 -lpthread
5.运行及其结果
$ ./test
test: hello world!
test: hello world!
test: hello world!
test: hello world!
try to expire timer!
test: hello c++11!
test: hello c++11!
try to expire timer!
test: hello c++11!
test: hello c++11!
test: hello world!
test: hello c++!
网友评论