C++11实现高精度定时器、计时器

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值