C++ 固定时间定时执行逻辑 - 二分定点法

  • 定时任务 - 二分定点法

  • 简介: 有需要例如每日晚上十二点整点执行清除某些数据或者做定期信息更新时需要用到这种逻辑、该逻辑是我认为比较节省资源与精准的逻辑,若有觉得不对的地方可以补充一下
  • 优点: 节省CPU损耗,不需要频繁检测当前时间
  • 缺点: 若更改系统时间,有可能会导致当天定时无法触发
  • 架构: 每次睡眠时间 (目标时间 - 当前时间)÷ 2
CrrentTime 15:00:00
Sleep 04:30:00
Sleep 02:15:00
Sleep 01:07:30
...
DstTime 24:00:00
  • : 每日 正点0时执行

//C++ 11
#include <chrono>
#include <thread>


{
	//时区 - cst时间戳是从1970-01-01 08:00:00开始计时
	static const uint32_t nTimestampZone = 8 * 60 * 60;

    //一整天所需要的秒数
	static const uint64_t nWholeDaySec = 24 * 60 * 60;

	//偏差范围 - 目标12:00:00 -> 实际允许 12:00:00 ~ 12:00:20
	static const uint32_t nDeviationAreaSec = 20;

    //目标时间
	static const uint8_t nDstHour = 0;
	static const uint8_t nDstMinute = 0;
	static const uint8_t nDstSec = 0;
	static const uint32_t nDstTimestampSec = (nDstHour * 60 * 60) + (nDstMinute * 60) + (nDstSec);

	//今日是否已经执行过
	bool bExecuted = false;

    	uint64_t nTime = 0;

	while (true)
	{
#ifdef __cplusplus > 201103L	//C++11
		//此处使用C++ 11(顺带了解C++11) - 可根据自己环境更改时间方法n
		//获取系统时间 + 8:00:00 ; 因为cst时间戳是从1970-01-01 08:00:00开始计时的
		//可以查找方法将 CST时间戳自动转换成UTC时间戳 但我没找到方法,因此只能写死的8:00:00
		nTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()) + nTimestampZone;
#else
		//C语言中的time
		nTime = time(nullptr) + nTimestampZone;
		//std::localtime(&nTimet);
#endif
		
		//实际偏差
		int32_t nDeviation = nTime % nWholeDaySec - nDstTimestampSec;

		//偏差在一定范围内
		if (!bExecuted && nDeviation <= nDeviationAreaSec  && nDeviation >= 0)
		{

			//执行相应处理
			bExecuted = true;
			
			/**
			*
			* * do something
			* 
			**/

			printf("Execute\n for Current Time [%02d:%02d:%02d]\n\n", nTime / 60 / 60, nTime / 60 % 60, nTime % 60);

			continue;
		}
		else if (bExecuted && nDeviation <= nDeviationAreaSec && nDeviation >= 0)
		{
			//仍在区间范围内 则直接跳过
			std::this_thread::sleep_for(std::chrono::seconds(1));
			
			printf("Sleep Once in the Current Area \n");
			
			continue;
		}
		else if (bExecuted && (nDeviation > nDeviationAreaSec || nDeviation < 0))
		{
			//经过区间范围之外
			bExecuted = false;
			continue;
		}



		static uint32_t nNeedSleep = 0;
		nNeedSleep = (nDeviation > 0 ? nWholeDaySec - nDeviation : (abs(nDeviation))) / 2;
		if (nNeedSleep == 1)
		{
			std::this_thread::sleep_for(std::chrono::milliseconds(100));

			printf("Sleep once for [100 milliseconds]\n\n");

			continue;
		}

		printf("Sleep once for [%d second]\n\n", nNeedSleep);

		//睡眠偏差值
		std::this_thread::sleep_for(std::chrono::seconds(nNeedSleep));

	}
}

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值