本文只做记录使用,方便后续查找,感谢作者!
CTime.h文件
#ifndef EXCAVATORSERVICE_CTIMER_H
#define EXCAVATORSERVICE_CTIMER_H
#include <functional>
#include <chrono>
#include <thread>
#include <atomic>
#include <memory>
#include <mutex>
#include <condition_variable>
class CTimer {
public:
CTimer(const CTimer& timer)
{
_expired = timer._expired.load();
_try_to_expire = timer._try_to_expire.load();
}
~CTimer()
{
stop();
}
void start(int interval, std::function<void()> task)
{
// is started, do not start again
if (_expired == false)
return;
// start async timer, launch thread and wait in that thread
_expired = false;
std::thread([this, interval, task]() {
while (!_try_to_expire)
{
// sleep every interval and do the task again and again until times up
std::this_thread::sleep_for(std::chrono::milliseconds(interval));
task();
}
{
// timer be stopped, update the condition variable expired and wake main thread
std::lock_guard<std::mutex> locker(_mutex);
_expired = true;
_expired_cond.notify_one();
}
}).detach();
}
void startOnce(int delay, std::function<void()> task)
{
std::thread([delay, task]() {
std::this_thread::sleep_for(std::chrono::milliseconds(delay));
task();
}).detach();
}
void stop()
{
// do not stop again
if (_expired)
return;
if (_try_to_expire)
return;
// wait until timer
_try_to_expire = true; // change this bool value to make timer while loop stop
{
std::unique_lock<std::mutex> locker(_mutex);
_expired_cond.wait(locker, [this] {return _expired == true; });
// reset the timer
if (_expired == true)
_try_to_expire = false;
}
}
CTimer(): _expired(true), _try_to_expire(false){}
private:
std::atomic<bool> _expired; // timer stopped status
std::atomic<bool> _try_to_expire; // timer is in stop process
std::mutex _mutex;
std::condition_variable _expired_cond;
};
#endif //EXCAVATORSERVICE_CTIMER_H
main.app 调用
void func2(){
cout<<"func2:"<<time(0)<<endl;
}
void func3(){
cout<<"func3:"<<time(0)<<endl;
}
int main() {
CTimer timer;
timer.start(5000, std::bind(func2));
timer.startOnce(1000, std::bind(func3));
cout<<"flage 1"<<endl;
sleep(10);
timer.stop();
cout<<"flage 2"<<endl;
getchar();
return 0;
}