定时器 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;     }        }     }}

欢迎交流

相关推荐

  1. 51单片机基础C语言):定时器时钟

    2024-03-29 23:32:02       55 阅读
  2. C++ 基础组件(1)定时器

    2024-03-29 23:32:02       41 阅读
  3. 基础时间线柱状图绘制

    2024-03-29 23:32:02       37 阅读
  4. QT时间日期与定时器

    2024-03-29 23:32:02       46 阅读
  5. C#实现定时执行+线

    2024-03-29 23:32:02       22 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-29 23:32:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-29 23:32:02       101 阅读
  3. 在Django里面运行非项目文件

    2024-03-29 23:32:02       82 阅读
  4. Python语言-面向对象

    2024-03-29 23:32:02       91 阅读

热门阅读

  1. 速成软件书:真的是神器吗?

    2024-03-29 23:32:02       44 阅读
  2. 战略定位--选择什么赛道。成为什么样的企业。

    2024-03-29 23:32:02       35 阅读
  3. Ubuntu22.04安装WordPress教程

    2024-03-29 23:32:02       35 阅读
  4. CCF-CSP认证考试 202212-4 聚集方差 100分题解

    2024-03-29 23:32:02       32 阅读
  5. 基于机器视觉的智能物流机器人的设计与开发

    2024-03-29 23:32:02       30 阅读
  6. 基于AOP实现自定义注解

    2024-03-29 23:32:02       39 阅读
  7. ARM的开源硬件

    2024-03-29 23:32:02       41 阅读
  8. Golang中四种gRPC模式

    2024-03-29 23:32:02       37 阅读
  9. git 合并当前分支到 指定仓库的指定分支

    2024-03-29 23:32:02       44 阅读
  10. 学习没有速成可言

    2024-03-29 23:32:02       34 阅读
  11. 脏牛提权(靶机复现)

    2024-03-29 23:32:02       38 阅读
  12. Mybatis plus(一)

    2024-03-29 23:32:02       42 阅读