C++实现定时器

2023-11-15

定时器的主要数据:
   1.一个线程变量,保存定时器线程
   2.一个互斥锁,配合条件变量使用
   3.一个条件变量,结合互斥锁,可以是线程不执行任务时,睡眠一段时间,在退出调用时,可以唤醒线程完成退出
   4.定时执行函数,具体的定时执行业务操作
   5.间隔时间,定时器间隔一段时间调用定时执行函数
   6.一个退出标识,标志是否退出定时线程循环
   7.立即执行标识,标识新建状态的定时线程是否立即执行一次任务,而不需等待一个间隔时间才开始执行第一次任务

#include <iostream>
#include <string>
#include <thread>
#include <chrono>
#include <atomic>
#include <memory>
#include <condition_variable>

using namespace std;


// 定时器类型
/*
   主要数据:
   1.一个线程变量,保存定时器线程
   2.一个互斥锁,配合条件变量使用
   3.一个条件变量,结合互斥锁,可以是线程不执行任务时,睡眠一段时间,在退出调用时,可以唤醒线程完成退出
   4.定时执行函数,具体的定时执行业务操作
   5.间隔时间,定时器间隔一段时间调用定时执行函数
   6.一个退出标识,标志是否退出定时线程循环
   7.立即执行标识,标识新建状态的定时线程是否立即执行一次任务,而不需等待一个间隔时间才开始执行第一次任务
*/
class CTimer
{
public:
	template<class F>
	CTimer(F func) 
		: m_func(func)
	{}

	virtual ~CTimer()
	{}

	// 启动函数
	void Start(unsigned int imsec, bool bimmediately_run = false)
	{
		cout << __FUNCTION__ << endl;
		if (imsec == 0 || imsec == static_cast<unsigned int>(-1)) // 间隔时间为0或默认无效值,直接返回
		{
			return;
		}
		m_bexit.store(false);
		m_imsec = imsec;
		m_bimmediately_run.store(bimmediately_run);
		m_thread = std::thread(std::bind(&CTimer::Run,this));
	}

	// 结束
	void Stop()
	{
		cout << __FUNCTION__ << endl;
		m_bexit.store(true);
		m_cond.notify_all(); // 唤醒线程
		if (m_thread.joinable())
		{
			m_thread.join();
		}
	}

	void SetExit(bool b_exit)
	{
		m_bexit.store(b_exit);
	}

private:
	void Run()
	{
		if (m_bimmediately_run.load()) // 立即执行判断
		{
			if (m_func)
			{
				m_func();
			}
		}

		while (!m_bexit.load())
		{
			{
				// 锁放在花括号内部,减小锁的粒度
				std::unique_lock<std::mutex> locker(m_mutex);
			
				// 如果是被唤醒的,需要判断先条件确定是不是虚假唤醒
                // wait_for是等待第三个参数满足条件,当不满足时,超时后继续往下执行
				m_cond.wait_for(locker, std::chrono::milliseconds(m_imsec), [this]() { return m_bexit.load(); });
			}

			if (m_bexit.load()) // 再校验下退出标识
			{
				return;
			}

			if (m_func)
			{
				m_func();
			}
		}
	}

private: // 私有数据部分
	std::atomic_bool m_bexit = false;
	std::atomic_bool m_bimmediately_run = false; // 是否立即执行
	unsigned int m_imsec = 1000;	// 间隔时间
	std::function<void()> m_func;	// 执行函数
	std::thread m_thread;
	std::mutex m_mutex;
	std::condition_variable m_cond;
};

int g_index = 0;

// 定时执行函数
void OnTimeFunc()
{
	cout << __FUNCTION__ << ":" << ++g_index << endl;
}

// 测试自己写的定时器
void Test_Timer()
{
	int index = 0;
	std::unique_ptr<CTimer> ptr_timer = std::make_unique<CTimer>(OnTimeFunc);
	if (ptr_timer == nullptr)
	{
		return;
	}
	ptr_timer->Start(1000);
	std::this_thread::sleep_for(std::chrono::seconds(10));

	ptr_timer->Stop(); // 离开作用已记得停止定时器
}


// 程序入口
int main()
{
	Test_Timer();

	cout << "getchar" << endl;
	getchar();
	return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++实现定时器 的相关文章

随机推荐

  • mysql笔记-mysql常用操作

    目录 一 中文汉字按照拼音首字母排序 二 case when then else end语法的使用 三 取两表并集 四 MySql8导入数据时insert插入数据慢 五 查看bin log日志 六 MySql常用运算符和函数 七 SQL语句
  • 【机器学习】机器学习简介

    一 定义 机器学习 Machine Learning ML 是一门多领域交叉学科 涉及概率论 统计学 逼近论 凸分析 算法复杂度理论等多门学科 专门研究计算机怎样模拟或实现人类的学习行为 以获取新的知识或技能 重新组织已有的知识结构使之不断
  • 开发者的Java测试用例浅析

    前段时间 在项目组里做了一点 java的 测试用例 虽然没有全自动化 也完成了半自动化的测试 比如 针对接口的测试 提供服务的测试等 都不需要启动服务 也不需要接口准备好 我们只需要知道输入输出 便可以进行testcase的编写 这样很方便
  • Failed to find Platform SDK with path: platforms;android-P

    坑大了 接收别人写的代码 clone下来的代码 run以后报Failed to find Platform SDK with path platforms android P这样的错误 当时一脸懵逼 最后全局搜索一下 Ctrl shift
  • STM32 电机教程 15 - BLDC 速度环内嵌电流环

    前言 无刷直流 Brushless Direct Current BLDC 电机是一种正快速普及的电机类型 它可在家用电器 汽车 航空航天 消费品 医疗 工业自动化设备和仪器等行业中使用 正如名称指出的那样 BLDC 电机不用电刷来换向 而
  • python中的requests,response.text与response.content及其编码

    文章目录 response的属性 1 response status code 2 response text 3 response content 4 response encoding 5 response apparent encod
  • mysql使用api详解_在MYSQL中如何使用API_MySQL

    5 2 选择API 本节介绍根据各种类型的应用程序选择A P I的方法 比较C DBI 和PHP API 的能力 并给出它们相对的优点和缺点 并指出什么时候应选择哪一个 首先应该指出 笔者不认为任一种语言优于其他语言 尽管笔者的确有自己的喜
  • 解决阿里云(ECS)等云主机服务端口的访问不通问题(安全组的坑)

    一 在现在阿里云 腾讯云 京东云等一系列的云主机的出现 作为开发者 将越来越多的服务搬上云主机上去了 二 但是在将服务 例如mysql redis等放在云主机上部署后 远程无法连接 其实是云主机安全组的坑 今天给忙活了一下午 三 配置安全组
  • 初等数据加密——对称加密算法

    对称加密算法是当今应用范围最广 使用频率最高的加密算法 根据加密方式分为密码和分组密码 分组密码工作模式又可分为ECB CBC CFB OFB和CTR等 密钥长度决定了加密算法的安全性 DES算法的使用 DES Data Encryptio
  • Unity实现鼠标点击指定位置导航角色

    实现目标 使用组件 一个场地 导航代理 摄像机 实现 进入游戏 鼠标左键点击场景的任意位置 导航代理将自动前往指向位置 步骤 首先我们需要一个场景 新建一平面作为场景地面 如果需要额外的障碍物则自己设置 这里不额外添加 然后在平面上放置一胶
  • Kubernetes(k8s)读记(一)

    Kubernetes 概述 Kubernetes 源于希腊语 意为 舵手 或 飞行员 k8s 这个缩写是因为 k 和 s 之间有八个字符的关系 Google 在 2014 年开源了 Kubernetes 项目 开源 用于管理云平台中多个主机
  • RabbitMQ-死信队列

    文章目录 前言 简介 使用Java代码创建和配置死信队列 死信队列的优缺点 总结 前言 当涉及到处理消息队列中无法正常消费的消息时 RabbitMQ的死信队列 Dead Letter Queue DLQ 是一个关键概念 在这篇博客中 我们将
  • 个人买保险扫盲

    1 购买保险原则总结 一般人都是有医保的 小孩也可以去社区买 这个是最基础的保障 一定要买 推荐的商业保险顺序 意外险 医疗险 gt 重疾险 gt 定期寿险 然后再是其他种类的保险等 意外和重大疾病是最有可能突然需要大笔资金花费的 对于普通
  • 图像识别中——目标分割、目标识别、目标检测和目标跟踪的区别

    计算机视觉旨在识别和理解图像 视频中的内容 包含四大基本任务 分类 图a 定位 检测 图b 语义分割 图c 和实例分割 图d 这四个任务需要对图像的理解逐步深入 给定一张输入图像 图像分类任务旨在判断该图像所属类别 目标定位是在图像分类的基
  • WebLogic Server 远程代码执行漏洞复现 (CVE-2023-21839)

    1 产品简介 Oracle WebLogic Server是一个统一的可扩展平台 用于在本地和云端开发 部署和运行企业应用程序 例如 Java WebLogic Server提供了Java Enterprise Edition EE 和Ja
  • Chatgpt介绍及搭建步骤

    ChatGPT是一个基于自然语言处理技术的聊天机器人 它使用了深度学习和语义分析技术 可以与用户进行自然 流畅的对话 ChatGPT可以回答各种问题 包括常见问题 娱乐 健康 技术 旅游 金融等领域 ChatGPT的核心技术是GPT Gen
  • java用正则表达式脱敏手机号

    一种正则形式 在Java开发中有时候需要对敏感字段数据脱敏 废话不多说 直接上代码 脱敏手机号 param str return 脱敏后字符串 public static String maskPhone String str return
  • Java变量的作用域:静态变量、全局变量和局部变量

    变量的作用域规定了变量所能使用的范围 只有在作用域范围内变量才能被使用 根据变量声明地点的不同 变量的作用域也不同 根据作用域的不同 一般将变量分为不同的类型 成员变量和局部变量 下面对这几种变量进行详细说明 成员变量 Java 的成员变量
  • Linux环境下PostgreSQL9.6+PostGIS2.5安装

    空间数据库原理上机实习要用 安了好久终于成功辽 由于在腾讯云上买好了服务器 所以直接远程登录了 一 PostgreSQL安装 1 导入yum源 sudo yum install y https download postgresql org
  • C++实现定时器

    定时器的主要数据 1 一个线程变量 保存定时器线程 2 一个互斥锁 配合条件变量使用 3 一个条件变量 结合互斥锁 可以是线程不执行任务时 睡眠一段时间 在退出调用时 可以唤醒线程完成退出 4 定时执行函数 具体的定时执行业务操作 5 间隔