定时器 c++ 基于时间线

获取当前时间std::chrono::system_clock::now();

std::chrono::time_point_cast<std::chrono::milliseconds>(now) 是 std::chrono 标准库中的一个函数调用,用于将时间点 now 转换为毫秒级别精度的时间点。

friend class timermanger; 表示将类 timermanger 声明为当前类的友元类。当一个类被声明为另一个类的友元类时,这意味着被声明为友元类的类可以访问声明它为友元的类的私有成员。

就是现有时间上,根据给的时间间隔,去执行相对应的数,把这个时间间隔发生的事件按照大小存储在map里

原.cpp

#include <iostream>
#include <string>
#include <thread>
#include "标头.h"
#include "timemanger.h"
using std::string;
void foo1()
{
    std::cout << "1000" << std::endl;
}
void foo2()
{
    std::cout << "1001" << std::endl;
}
void bar(const string& name)
{
    std::cout << "bar:" << name << std::endl;
}
int main()
{
    timemanger mar1;
    mar1.schedule(1000,5,foo1);//注册定时任务    
    mar1.schedule(1001,3, foo2);
    while (true) {
        mar1.update();}//触发定时任务
    return 0;
}
Timer.h
#pragma once
#include<functional>;
#include<iostream>;

    class timer {
      friend class timemanger;
    public:
      timer();
      timer(int repeat);
      ~timer();
      template<typename F, typename ...Arges>
      void callback(int milliseconds, F&& f, Arges&& ...arges);
      void on_timer();
    
      int m_time;//定时器触发的时间点
      int m_period;//定时器触发的周期
      std::function<void()>m_func;
      int m_repeat;//定时器触发的次数,-1无限触发
      static int now();
    };
    template<typename F, typename ...Arges>
    inline void timer::callback(int milliseconds, F&& f, Arges&& ...arges)
    {
      m_period = milliseconds;
      //每个绑定的函数对象可以传递不同的参数。
      m_func = std::bind(std::forward<F>(f), std::forward < Arges>(arges)...);}
timer.cpp
#include "标头.h"
#include<chrono>
#include<ctime>
timer::timer():m_period(0),m_repeat(-1)
{
  m_time = now();
}
timer::timer(int repeat): m_period(0), m_repeat(repeat)
{
  m_time = now();
}
timer::~timer()
{
}
void timer::on_timer()
{
  if (!m_func || m_repeat == 0)
    return ;//void函数用
  m_func();//执行任务
  m_time += m_period;更新时间,因为m_time是从now那里获取的当前时间
  if (m_repeat > 0)m_repeat--;//触发次数减少
}
int timer::now()
{//获取当前时间
  auto now = std::chrono::system_clock::now();
//再把当前时间点转换为毫秒数,c++11里面的时间库
  auto now_hs = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
  //我们计算了从系统纪元到时间点 now_hs 的时间间隔,并以毫秒为单位表示
  //最后,使用 count() 函数获取这个时间间隔的毫秒数值。
  return now_hs.time_since_epoch().count();
}
Timemanger.h

#pragma once
#include<map>
#include "标头.h"
class timemanger {
public:
  timemanger() = default;
  ~timemanger() = default;

  //std::multimap 是 C++ 标准库中提供的一个关联容器,它类似于 std::map,但允许键(key)重复,排序,通过key知道下一个触发时间
  std::multimap<int, timer>m_timers;

  template<typename F,typename ...Arges>
  void schedule(int milliseconds, F&& f, Arges&& ...arges);//F是函数,然后f是他可以接受的可变参数
  template<typename F, typename ...Arges>
  void schedule(int milliseconds,int repeat, F&& f, Arges&& ...arges);
  void update();
};

template<typename F, typename ...Arges>
inline void timemanger::schedule(int milliseconds, F&& f, Arges && ...arges)
{
  schedule(milliseconds, -1, std::forward<F>(f), std::forward<Arges>(arges)...);
}

template<typename F, typename ...Arges>
inline void timemanger::schedule(int milliseconds, int repeat, F&& f, Arges && ...arges)
{
  timer t(repeat);

  t.callback(milliseconds, std::forward<F>(f), std::forward<Arges>(arges)...);
  m_timers.insert(std::make_pair(t.m_time, t)); 
}
Timemanger.cpp
#include "timemanger.h"
void timemanger::update()
{
  if (m_timers.empty())  return;
  int now= timer::now();

  for (auto it = m_timers.begin(); it != m_timers.end();) {
    if (it->first > now)
      return;
    it->second.on_timer();
    timer t = it->second;
    it = m_timers.erase(it); 
    if (t.m_repeat!= 0)
    {
      auto new_it = m_timers.insert(std::make_pair(t.m_time, t));
      if (it == m_timers.end()||new_it->first<it->first) {
        it = new_it;     }        }     }}

欢迎交流

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/487697.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

24年3月下半笔记(个人向)(更新中)

3.19 开始复工复产了 发现poe网站上可以免费用chatgpt&#xff0c;用了两天就彻底产生依赖性了 继续看d2l&#xff0c;之前看到第三章结束&#xff0c;今天从4.1看到4.6 第四章讲mlp&#xff0c;老生常谈&#xff0c;各种激活函数ReLU、sigmoid、tanh 然后是防止过拟合&am…

Verilog刷题笔记43

题目&#xff1a;Exams/m2014 q4b 解题&#xff1a; module top_module (input clk,input d, input ar, // asynchronous resetoutput q);always(posedge clk,posedge ar)beginif(ar1)q<0;elseq<d;endendmodule结果正确&#xff1a; 补充&#xff1a; 同步复位和异步…

Jenkins+Ant+Jmeter接口自动化集成测试详解

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、Jenkins安装配置 1、安装配置JDK1.6环境变量&#xff1b; …

抓取京东/淘宝类数据#Javascript#商品详情图片

提出问题 如何在京东商城爬取出各个商品的相关信息(价格、名称、评价、店铺名等等)&#xff0c;比如&#xff0c;打开web京东网站&#xff0c;那么商品展示列表的所有商品的信息&#xff0c;怎么爬下来&#xff0c;怎么保存到表格中&#xff1f; 我们来看看怎么实现这个功能。…

手写springboot启动器, 学习SpringBoot的最佳实践

自己手写的SpringBoot启动器, 是一个学习了解SpringBoot启动逻辑和了解springboot原理的不错的实践Demo. 废话不多说,直接上代码: 项目结构 maven多项目结构, myspringboot 自己手写的SpringBoot启动器 service-demo 用来测试SpringBoot启动器的示例项目 项目pom依赖 1.…

Istio 部署 Spring Coud 微服务应用

Istio 服务部署 这篇文章讲述如何将 Java Spring Cloud 微服务应用部署到 Istio mesh 中。 准备基础环境 使用 Kind 模拟 kubernetes 环境。文章参考&#xff1a;https://blog.csdn.net/qq_52397471/article/details/135715485 在 kubernetes cluster 中安装 Istio 创建一…

接口用例之好用例和坏用例

自动化测试的重要性显而易见&#xff0c;但自动化测试又无法解决所有问题&#xff0c;所以说完全依赖自动化是不可能的&#xff0c;但完全没有自动化是万万不能。在软件开发项目中&#xff0c;重度依赖人力进行持续回归是一件非常枯燥的重复工作。企业需要花费大量的时间和金钱…

代码随想录算法训练营第33天|1005.K次取反后最大化的数组和|134. 加油站|135. 分发糖果

代码随想录算法训练营第33天|1005.K次取反后最大化的数组和|134. 加油站|135. 分发糖果 1005.K次取反后最大化的数组和 本题简单一些&#xff0c;估计大家不用想着贪心 &#xff0c;用自己直觉也会有思路。 https://programmercarl.com/1005.K%E6%AC%A1%E5%8F%96%E5%8F%8D%E5%…

【QA】MySQL导出某数据库的所有数据为sql文件,包含建库命令、建表命令。

文章目录 前言Windows系统下 | mysqldump导出数据库数据Docker中导入初始化数据【补充】通过命令行&#xff0c;执行sql文件&#xff0c;将数据导入到数据库在MySQL外面执行在MySQL中执行 前言 我们在用docker部署mysql项目的时候&#xff0c;往往需要对数据库进行数据初始化。…

PLC_博图系列☞RS:复位/置位触发器

PLC_博图系列☞RS&#xff1a;复位/置位触发器 文章目录 PLC_博图系列☞RS&#xff1a;复位/置位触发器背景介绍RS&#xff1a;复位/置位触发器说明参数示例 关键字&#xff1a; PLC、 西门子、 博图、 Siemens 、 RS 背景介绍 这是一篇关于PLC编程的文章&#xff0c;特别…

蓝桥杯java---螺旋矩阵

解题思路&#xff1a; int [][] arr new int[n][m];int i 0, j -1, temp 1;while (n * m > 0){for (int p 0; p < m; p)//从左自右arr[i][jj1] temp;n--;if (n * m 0) break;for (int p 0; p < n; p)//从上自下arr[ii1][j] temp;m--;if (n * m 0) break;fo…

使用HiBurn烧录鸿蒙.bin文件到Hi3861开发板

鸿蒙官方文档的“Hi3861开发板第一个示例程序”中描述了——如何使用DevEco Device Tool工具烧录二进制文件到Hi3861开发板&#xff1b; 本文将介绍如何使用HiBurn工具烧录鸿蒙的.bin文件到Hi3861开发板。 获取HiBurn工具 通过鸿蒙官方文档我们知道DevEco Device Tool是一个V…

C语言:自定义类型:联合体和枚举

目录 联合体 联合体是什么&#xff1f; 联合体的大小计算 枚举 枚举是什么&#xff1f; 为什么要使用枚举&#xff1f; 联合体 联合体是什么&#xff1f; 联合体也是个自定义类型&#xff0c;它和结构体类似&#xff0c;都是由多个成员构成&#xff0c;可以有不同的内置…

【Java八股面试系列】中间件-Redis

目录 Redis 什么是Redis Redis解决了什么问题 Redis的实现原理 数据结构 String 常用命令 应用场景 List(列表) 常用命令 应用场景 Hash(哈希) 常用命令 应用场景 set(集合) 常见命令​编辑 应用场景 Sorted Set(有序集合) 常见命令​编辑 应用场景 数据持…

【数据结构】线性表的定义与基本操作

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;数据结构 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

【搭建私人图床】本地PHP搭建简单Imagewheel云图床,在外远程访问

目录 ⛳️推荐 1.前言 2. Imagewheel网站搭建 2.1. Imagewheel下载和安装 2.2. Imagewheel网页测试 2.3.cpolar的安装和注册 3.本地网页发布 3.1.Cpolar临时数据隧道 3.2.Cpolar稳定隧道&#xff08;云端设置&#xff09; 3.3.Cpolar稳定隧道&#xff08;本地设置&…

JavaScript 基础、内置对象、BOM 和 DOM 常用英文单词总结

一提到编程、软件、代码。对于英语不是很熟悉的同学望而却步。其实没有想像中的难么难&#xff0c;反复练习加上自己的思考、总结&#xff0c;会形成肌肉记忆。整理一下&#xff0c;初学者每天30遍。 1、JavaScript 基础语法 break&#xff1a;中断循环或 switch 语句的执行。…

ISAC代码仿真学习笔记

文章目录 A. MIMO Communication ModelB. MIMO Radar Model III. Joint Waveform and Phase Shift Matrix Design for Given Radar BeampatternA. Problem FormulationB. Proposed Algorithm V. S IMULATION RESULTS A. MIMO Communication Model 用户处的接收信号矩阵由 Y …

IO流之字符流实战

IO流&#xff08;一&#xff09;字符流 一、IO流是什么&#xff1f;二、File类三、引入IO流四、代码演示例题&#xff1a;通过java程序完成文件的复制操作从文件中读取数据&#xff08;一个一个读&#xff09;向文件中写入数据&#xff08;一个一个写&#xff09;利用缓冲数组读…

景泓达智能科技邀您参观2024第七届燕窝及天然滋补品博览会

2024第七届世界燕窝及天然滋补品博览会 2024年8月7-9日| 上海新国际博览中心 同期举办&#xff1a;第三届世界滋补产业生态大会暨交流晚宴/颁奖典礼 2024第九届酵素、益生产品博览会 2024上海国际月子健康博览会 2024上海燕博会经历了7年的发展与资源积累&#xff0c;已成为…