C++定时器实现和时间轮介绍

C++ 定时器实现和时间轮介绍

定时器是计算机系统中非常常见的一种机制,可以用来在一定时间间隔后执行某些操作,或在特定时间点执行某些操作。在 C++ 编程中,我们可以使用定时器来进行任务调度等操作。其中,时间轮是一种常见的定时器实现方式,下面将详细介绍时间轮的概念和实现,以及如何在 C++ 中进行定时器的编写。

什么是时间轮?

时间轮是一种基本的定时器实现方法,它将时间线划分成多个区间,每个区间代表一个时间间隔,每个槽位代表了一个定时任务。时间轮中还有一个指针,指向当前正在执行的槽位,每经过一个时间间隔,指针会向后移动一个槽位。当指针指向某个槽位时,就会执行该槽位中的定时任务。

时间轮的优点在于,可以快速定位到需要执行的定时任务,并且可以处理高并发的情况,即可以同时管理多个定时任务。

时间轮的实现方法

时间轮的实现方法相对简单,可以使用一个循环数组来存储各个槽位,使用一个指针来指向当前执行的槽位,每经过一个时间间隔,指针就会向后移动一个槽位。当执行到某个槽位时,就会执行该槽位中的所有定时任务。

具体实现可以分为以下步骤:

  1. 创建时间轮对象,存储循环数组和指针
  2. 向时间轮中添加定时任务,计算定时任务在时间轮中对应的槽位,将定时任务插入槽位
  3. 启动时间轮,开始执行定时任务
  4. 每经过一个时间间隔,指针向后移动一个槽位,并执行该槽位中的所有定时任务
  5. 当时间轮执行完一圈时,重新回到第一个槽位,继续执行定时任务,直到时间轮被停止

以下是使用 C++ 实现时间轮的代码示例:

#include <iostream>
#include <vector>
#include <functional>
#include <chrono>
#include <thread>

using namespace std::chrono_literals;

class Timer {
public:
    Timer(size_t wheelSize, size_t tickDuration)
        : m_wheelSize(wheelSize), m_tickDuration(tickDuration), m_currentTick(0), m_wheel(wheelSize), m_stop(false)
    {
        m_wheel[0].resize(0xffffffffu / wheelSize + 1);  // 根据 wheelSize 计算每个槽位能包含的最大超时时间
    }

    void start()
    {
        m_stop = false;
        m_ticksThread = std::thread([this] {
            while (!m_stop) {
                std::this_thread::sleep_for(m_tickDuration);
                onTick();
            }
        });
    }

    void stop()
    {
        m_stop = true;
        if (m_ticksThread.joinable()) {
            m_ticksThread.join();
        }
    }

    template <typename FuncType>
    void addTimer(size_t timeoutMs, FuncType&& func)
    {
        if (m_stop) {
            return;
        }
        auto wheelIdx = (m_currentTick + (timeoutMs / m_tickDuration)) % m_wheelSize;  // 获取任务应该插入的槽位
        auto& bucket = m_wheel[wheelIdx];
        bucket.emplace_back(std::forward<FuncType>(func));
    }

private:
    void onTick()
    {
        auto& bucket = m_wheel[m_currentTick % m_wheelSize];            
        for (auto& func : bucket) {  // 执行当前槽位中的任务
            func();
        }
        bucket.clear();
        m_currentTick = (m_currentTick + 1) % m_wheelSize;  // 将时间轮指针向后移动一个槽位
    }

private:
    size_t m_wheelSize;
    size_t m_tickDuration;
    size_t m_currentTick;
    std::vector<std::vector<std::function<void()>>> m_wheel;
    std::thread m_ticksThread;
    bool m_stop;
};

int main()
{
    Timer timer(60, 100ms);  // 创建时间轮,60 个槽位,每个槽位 100 ms
    timer.start();  // 启动时间轮

    for (int i = 0; i < 1000; i++) {  // 添加 1000 个定时任务
        timer.addTimer(i * 10, [i] {
            std::cout << "Task " << i << " is executed at " << std::chrono::system_clock::now().time_since_epoch().count() << std::endl;
        });
    }

    std::this_thread::sleep_for(15s);  // 等待 15s,让时间轮执行完毕

    timer.stop();  // 停止时间轮

    return 0;
}

使用 boost 实现定时器

除了手动实现时间轮,我们还可以使用 boost 库提供的定时器组件来实现定时器。下面是使用 boost 定时器组件实现定时器的代码示例:

#include <iostream>
#include <boost/asio.hpp>

using namespace boost::asio;

int main()
{
    io_service io;
    deadline_timer t(io, boost::posix_time::seconds(5));  // 创建一个定时器,5s 后触发

    t.wait();  // 等待定时器触发

    std::cout << "Timer is expired." << std::endl;

    return 0;
}

上面的代码创建了一个定时器,5s 后触发,使用 wait 函数等待定时器触发。需要注意的是,使用 boost 定时器组件时需要注意线程安全性问题。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++定时器实现和时间轮介绍 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • C语言调试手段:锁定错误的实现方法

    当我们编写C语言程序时,难免会出现各种错误。这时候,调试就是必不可少的工作。但是,要想顺利地调试程序,我们需要掌握一些调试手段。下面,我将详细讲解“C语言调试手段:锁定错误的实现方法”的完整攻略。 一、使用调试器 调试器是一种通过逐行执行程序并观察程序运行状态来找出程序中的错误的工具。使用调试器进行调试的时候,我们可以逐行执行程序,并且在程序运行的过程中查看…

    C 2023年5月24日
    00
  • c语言实现系统时间校正工具代码分享

    C语言实现系统时间校正工具代码分享 简介 本篇攻略将会介绍如何使用C语言实现一个系统时间校正工具。通过在代码中调用系统API和获取网络时间,来实现校准本地系统时间的功能,帮助用户更准确地记录时间,提高使用效率。 实现步骤 步骤一:引入头文件 首先,为了实现获取系统时间以及联网获取时间的功能,需要引入系统头文件time.h,以及获取网络时间需要用到的winso…

    C 2023年5月22日
    00
  • 如何用PyPy让你的Python代码运行得更快

    如何用 PyPy 让你的 Python 代码运行得更快 PyPy是一个相对于标准CPython实现的替代Python解释器。它使用即时编译(JIT)来加速Python代码的运行速度,并能够提供比CPython更好的垃圾回收和内存管理。 以下是使用PyPy优化Python代码的步骤: 步骤1:安装PyPy 在 PyPy 官方网站(https://www.pyp…

    C 2023年5月22日
    00
  • C++基础之this指针与另一种“多态”

    C++基础之this指针与另一种“多态” 1. this指针是什么? 在C++中,this指针有一个特殊的用途,它指向当前对象的指针。我们通常使用this指针来访问当前对象的成员变量和成员函数。 class Person { private: string name; public: Person(string name) { this->name =…

    C 2023年5月22日
    00
  • C语言指向指向常量的常量指针的指针

    “C语言指向指向常量的常量指针的指针”(const pointer to const pointer)是一个比较复杂的概念,它在C语言中用于处理指针的嵌套问题,即通过一个指针的指针来访问一个变量。下面来详细讲解它的用法及示例: 概述 在C语言中,指针是一个存储内存地址的变量,而指向指针的指针就是一个存储指针的内存地址的变量。而指向常量的常量指针则是一个不能够…

    C 2023年5月9日
    00
  • C语言实现通用数据结构之通用集合(HashSet)

    C 语言实现通用数据结构之通用集合(HashSet) 什么是 HashSet HashSet 是一种常用的数据结构,其实质就是一个无序不重复的元素集合。在 C 语言中,你可以使用 HashSet 存储任何类型的数据。 HashSet 的优点在于: 独立性,只关心数据的存储和操作,而不必关心数据类型; 方便性,对于处理过程,比起普通数组无需考虑顺序问题。 实现…

    C 2023年5月23日
    00
  • JSON字符串和对象相互转换实例分析

    下面就为您详细讲解“JSON字符串和对象相互转换实例分析”的完整攻略。 什么是JSON字符串和对象? JSON(JavaScript Object Notation)是一个轻量级的数据交换格式。它基于JavaScript的一个子集。JSON格式具有自我描述性,易于理解和阅读。同时也易于解析和生成,这使JSON成为数据交换和存储的常用格式。 JSON字符串 J…

    C 2023年5月23日
    00
  • iOS开发使用JSON解析网络数据

    iOS开发使用JSON解析网络数据 简介 在iOS开发中,经常需要从网络上获取数据并进行解析。JSON是一种轻量级的数据交换格式,在iOS开发中也常常使用JSON来传输和解析网络数据。本文将详细介绍在iOS开发中如何使用JSON来解析网络数据。 JSON的基本格式 JSON全称为JavaScript Object Notation,是一种轻量级的数据交换格式…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部