定时器 c++ 基于时间线

news2024/10/5 13:48:37

获取当前时间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;     }        }     }}

欢迎交流

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构入门学习③——栈和队列

前言&#xff1a; 本篇博客主要介绍有关栈和队列数据结构相关知识 思维导图介绍&#xff1a; 开始之前&#xff0c;先介绍一下这篇博客主要介绍的主体内容&#xff1a; 栈和队列&#xff1a; 回顾线性表&#xff1a; 在刚才的思维导图里我们也了解到了——栈和队列都属于线性…

【vscode打开多文件夹】

1)将文件夹添加到工作空间中 2)文件夹方式展开 3)最终效果 小技巧&#xff1a; 文件夹的位置不对的话&#xff0c;可以拖动进行调整。

3.24作业

基于UDP的网络聊天室 项目需求&#xff1a; 如果有用户登录&#xff0c;其他用户可以收到这个人的登录信息如果有人发送信息&#xff0c;其他用户可以收到这个人的群聊信息如果有人下线&#xff0c;其他用户可以收到这个人的下线信息服务器可以发送系统信息 服务器端代码 #in…

数据结构 之 队列习题 力扣oj(附加思路版)

优先级队列 #include<queue> --队列 和 优先级队列的头文件 优先级队列&#xff1a; 堆结构 最大堆 和 最小堆 相关函数&#xff1a; front() 获取第一个元素 back() 获取最后一个元素 push() 放入元素 pop() 弹出第一个元素 size() 计算队列中元素…

<网络>初识计算机网络

目录 一、网络发展 &#xff08;一&#xff09;背景 &#xff08;二&#xff09;类型 二、网络协议 &#xff08;一&#xff09;认识协议 &#xff08;二&#xff09;协议分层 &#xff08;三&#xff09;OSI七层模型 &#xff08;四&#xff09;TCP/IP五层模型 &…

[音视频学习笔记]八、FFMpeg结构体分析 -上一个项目用到的数据结构简单解析:AVFrame、AVFormatContext、AVCodecContext

前言 上次我们做了一个简单的视频解码&#xff0c;MediaPlay-FFmpeg - Public 这一次简单对这个代码进行一个剖析&#xff0c;对其中的数据结构进行一个解析。 这些数据结构之间的关系 AVFrame 、AVFormatContext 、AVCodecContext 、AVIOContext 、AVCodec 、AVStream 、AV…

Pillow教程01:初识Pillow模块(创建Image对象+查看属性+图片的保存与缩放)

--------------Pillow教程集合--------------- Python项目18&#xff1a;使用Pillow模块&#xff0c;随机生成4位数的图片验证码 Python教程93&#xff1a;初识Pillow模块&#xff08;创建Image对象查看属性图片的保存与缩放&#xff09; Pillow教程02&#xff1a;图片的裁剪…

【算法专题--双指针算法】leecode-15.三数之和(medium)、leecode-18. 四数之和(medium)

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 前言1. 三数之和2. 解法&…

如何使用PHP和RabbitMQ实现延迟队列(方式二)?

前言 前几天写了一篇关于PHP和RabbitMQ如何通过插件实现延迟队列的功能。 今天写另外一篇不需要插件的方式&#xff0c;使用RabbitMQ的死信队列&#xff08;Dead-Letter-Exchanges, DLX&#xff09;和消息TTL&#xff08;Time-To-Live&#xff09;。 这种方法涉及到设置消息…

OpenHarmony 源码解析之SystemUi—Statusbar(TS)

作者&#xff1a;董伟 简介 SystemUI应用是OpenHarmony中预置的系统应用&#xff0c;为用户提供系统相关信息展示及交互界面&#xff0c;包括系统状态、系统提示、系统提醒等&#xff0c;例如系统时间、电量信息。 本文主要分析batterycomponent、clockcomponent、wificompo…

C#自定义控件 生成 与 加入到项目

C#自定义控件生成 在C#中&#xff0c;自定义控件通常是通过继承现有的控件类&#xff08;如UserControl、Form等&#xff09;并添加或修改其属性和方法来实现的。以下是一个简单的示例&#xff0c;演示如何创建一个自定义控件&#xff1a; 首先&#xff0c;创建一个新的Window…

陪诊小程序成品|陪诊系统功能|陪诊小程序研发功能和流程

近年来&#xff0c;随着人们健康意识的提升和医疗行业的不断发展&#xff0c;陪诊小程序在医疗领域中扮演着越来越重要的角色。那么&#xff0c;什么是陪诊小程序&#xff1f;它具有怎样的功能和流程呢&#xff1f;本文将为您详细解读。 陪诊小程序是一种通过手机应用程序进行…

Ipython与Jupyter之间的关系

IPython 和 Jupyter 之间的关系可以从它们的历史和目标中得到很好的解释。IPython&#xff08;Interactive Python&#xff09;最初是由 Fernando Prez 于 2001 年创建的&#xff0c;旨在提升 Python 的交互式计算体验。它提供了一个强大的交互式 Python shell 和一个面向高效计…

Arduino IDE工程代码多文件编程和中文设置

一、esp8266模块信息 二、中英文切换 点击文件( File )–选择首选项( Preference )—选择语言( Language )—选择中文–点击确定( OK ) 三、多文件编程 在Arduino编程中&#xff0c;将代码分割成多个文件是一种很好的做法&#xff0c;特别是项目变得越来越大和复杂时。这样…

基于nodejs+vue基于hive旅游数据的分析与应用python-flask-django-php

系统阐述的是使用基于hive旅游数据的分析与应用系统&#xff0c;对于nodejs结构、MySql进行了较为深入的学习与应用。主要针对系统的设计&#xff0c;描述&#xff0c;实现和分析与测试方面来表明开发的过程。开发中使用了express框架和MySql数据库技术搭建系统的整体架构。利用…

【爬虫框架pyspider】02 - pyspider 用法详解

pyspider 用法详解 前面我们了解了 pyspider 的基本用法&#xff0c;我们通过非常少的代码和便捷的可视化操作就完成了一个爬虫的编写&#xff0c;本节我们来总结一下它的详细用法。 1. 命令行 上面的实例通过如下命令启动 pyspider&#xff1a; pyspider all 命令行还有很…

如何调用occtproxy放入自己的wpf文件

1.创建一个wpf程序 2.添加项目occtproxy.vcxproj 3.把该项目配置类型设为dll 4.添加引用 5.报错显示&#xff0c;这是因为还没有生成dll 6.把occtproxy设为启动项目运行&#xff0c;设定输出目录在该目录下&#xff0c;生成dll 7.再运行&#xff0c;即可

基于Colab训练的yolov4-tiny自定义数据集(可用于OpenCV For Unity)

参考资料文档和视频。 1.打开文档,点击【文件】【在云端硬盘中保存一份副本】,即将文档复制到自己云端硬盘。 2.打开该文件,按文中提示进行。 【代码执行程序】【更改运行时类型】修改运行时为GPU(免费的GPU不好用,收费的好用,某宝上几十元就可用一个月) 步骤1) !git…

日新增百万数据clickhouse大数据解决方案记录分享

公司广告业务需求&#xff0c;需要多个维度统计每个应用的设备数&#xff0c;点击率&#xff0c;展示率&#xff0c;等相关数据&#xff0c;而且数据需要进行去重&#xff0c;我第一时间想到的是利用clickhouse来做统计&#xff0c;因为我们平台访问量比较大&#xff0c;用mysq…

STM32-01基于HAL库(CubeMX+MDK+Proteus)仿真开发环境搭建(LED点亮测试实例)

STM32-01基于HAL库&#xff08;CubeMXMDKProteus&#xff09;仿真开发环境搭建&#xff08;LED点亮测试实例&#xff09; 一、 开发工具版本列表二、安装过程三、实例测试&#xff08;点亮单个LED&#xff09;0、功能需求分析1、Proteus绘制电路原理图2、STMCubeMX 配置引脚及模…