C++11实现高精度定时器、计时器
直接上代码
#pragma once
#ifndef _TIMER_H_
#define _TIMER_H_
#include <functional>
#include <chrono>
#include <thread>
#include <atomic>
#include <memory>
#include <mutex>
#include <condition_variable>
#include <Windows.h>
using namespace std;
class TimeRecord
{
public:
TimeRecord() : m_beginTime(chrono::high_resolution_clock::now()) {}
void reset() { m_beginTime = chrono::high_resolution_clock::now(); }
//return milliseconds
int64_t elapsed() const
{
return chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - m_beginTime).count();
}
//return microseconds
int64_t elapsed_micro() const
{
return chrono::duration_cast<chrono::microseconds>(chrono::high_resolution_clock::now() - m_beginTime).count();
}
//return nanoseconds
int64_t elapsed_nano() const
{
return chrono::duration_cast<chrono::nanoseconds>(chrono::high_resolution_clock::now() - m_beginTime).count();
}
//return seconds
int64_t elapsed_seconds() const
{
return chrono::duration_cast<chrono::seconds>(chrono::high_resolution_clock::now() - m_beginTime).count();
}
//return minutes
int64_t elapsed_minutes() const
{
return chrono::duration_cast<chrono::minutes>(chrono::high_resolution_clock::now() - m_beginTime).count();
}
//return hours
int64_t elapsed_hours() const
{
return chrono::duration_cast<chrono::hours>(chrono::high_resolution_clock::now() - m_beginTime).count();
}
private:
chrono::time_point<chrono::high_resolution_clock> m_beginTime;
};
class Timer
{
public:
Timer() : m_expired(true), m_tryToExpire(false){}
Timer(const Timer& timer)
{
m_expired = timer.m_expired.load();
m_tryToExpire = timer.m_tryToExpire.load();
}
~Timer()
{
stop();
}
//sleep for milliseconds
void millSleep(long milliseconds)
{
LARGE_INTEGER litmp;
LONGLONG QPart1, QPart2;
double dfMinus, dfFreq, dfTim, dfSpec;
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadPart;
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadPart;
dfSpec = 0.001*milliseconds;
do
{
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadPart;
dfMinus = (double)(QPart2 - QPart1);
dfTim = dfMinus / dfFreq;
} while (dfTim < dfSpec);
}
void startOnce(int delay, function<void()> task)
{
thread([delay, task]() {
this_thread::sleep_for(chrono::milliseconds(delay));
task();
}).detach();
}
void start(int interval, function<void()> task)
{
// is started, do not start again
if (m_expired == false)
return;
// start async timer, launch thread and wait in that thread
m_expired = false;
thread([this, interval, task]() {
while (!m_tryToExpire)
{
// sleep every interval and do the task again and again until times up
//this_thread::sleep_for(chrono::milliseconds(interval)); There is an error of about 10 milliseconds
millSleep(interval);
task();
}
{
// timer be stopped, update the condition variable expired and wake main thread
lock_guard<mutex> locker(m_mutex);
m_expired = true;
m_expiredCond.notify_one();
}
}).detach();
}
void stop()
{
// do not stop again
if (m_expired)
return;
if (m_tryToExpire)
return;
// wait until timer
m_tryToExpire = true; // change this bool value to make timer while loop stop
{
unique_lock<mutex> locker(m_mutex);
m_expiredCond.wait(locker, [this] {return m_expired == true; });
// reset the timer
if (m_expired == true)
m_tryToExpire = false;
}
}
private:
atomic<bool> m_expired; // timer stopped status
atomic<bool> m_tryToExpire; // timer is in stop process
mutex m_mutex;
condition_variable m_expiredCond;
};
#endif /
测试代码
Timer timer;
std::cout << "--- start period timer ----" << std::endl;
timer.start(10, std::bind(func2, 3));
std::cout << "--- stop period timer ----" << std::endl;
timer.stop();
参考文档
https://zhuanlan.zhihu.com/p/64746342
https://www.bbsmax.com/A/WpdKgpLndV/
https://blog.csdn.net/zj1131190425/article/details/98777584
https://www.runoob.com/cplusplus/cpp-date-time.html
https://blog.csdn.net/wangningyu/article/details/82051206