C++11实现简易定时器的示例代码

下面是关于“C++11实现简易定时器的示例代码”的完整攻略。

标题

C++11实现简易定时器的示例代码

简介

在开发事件驱动或多线程程序时,经常需要一种定时器来控制任务的执行时间。本篇攻略将介绍如何使用C++11编写一个简易的定时器,以此来满足我们在各种场景中的需求。

本攻略将包含两个实例展示如何使用简易定时器,读者可以通过这两个实例学习如何将其应用于自己的项目中。

攻略步骤

1.头文件定义

第一步是定义必需的头文件:<thread><functional><chrono><atomic>

c++
#include <thread>
#include <functional>
#include <chrono>
#include <atomic>
using namespace std;

2.声明实现定时器类

声明并定义一个 Timer 类,包含私有成员变量和公共成员函数声明:

 class Timer
 {
 public:
     Timer() = default;
     Timer(const Timer &t) = delete;
     Timer(Timer &&t) = delete;
     ~Timer();

     void start(int32_t interval, function<void(void)> func);
     void stop();

 private:
     void thread_proc();

 private:
     atomic<bool> m_running{ false };
     int32_t m_interval{ 0 };
     function<void(void)> m_func;
     thread m_thread;
 };

在这里,我们使用了C++11中的原子变量 atomic,其中,在开始定时器时设置为真,在停止定时器时设置为假,并在整个执行过程中用于同步线程。

同时,我们采用函数指针获取定时器执行任务过程中调用的函数,这样可以方便定制任务代码。

3.实现定时器类

接下来我们来实现 Timer 类。

3.1 开始定时器

在开始定时器时,我们首先要记住 intervalfunc 参数。然后启动一个线程来执行定时器逻辑:

 void Timer::start(int32_t interval, function<void(void)> func) {
     m_interval = interval;
     m_func = std::move(func);
     m_running = true;
     m_thread = thread(&Timer::thread_proc, this);
 }

3.2 执行定时器任务

定时器的主要任务是在指定的时间间隔内重复执行特定任务,因此我们需要使用 C++ 11 的 chrono 库来实现计时器。在 thread_proc 函数中,我们将使线程保持在一直执行状态,直到定时器停止。

 void Timer::thread_proc() {
     while (m_running) {
         this_thread::sleep_for(chrono::milliseconds(m_interval));
         if (m_running) {
             m_func();
         }
     }
 }

3.3 停止定时器

停止定时器很简单,只需先将 m_running 标志设置为 false ,停止线程,在等待线程退出:

 void Timer::stop() {
     m_running = false;
     if (m_thread.joinable()) {
         m_thread.join();
     }
 }

4.使用案例

经过前面的步骤,我们已经成功实现了一个简单的定时器,现在来看看如何在实际项目中使用它。

4.1 基本使用

下面是基本示例,演示如何每隔1秒钟打印一次字符串:

Timer timer;
timer.start(1000, []() { cout << "Hello, World!" << endl; });
this_thread::sleep_for(chrono::seconds(5));
timer.stop();

在这个示例中,我们首先创建了一个 Timer 对象,然后调用 start 函数来开启定时器,参数 interval 是 1000 毫秒表示 1 秒钟,func 是一个函数(lambda 表达式)句柄,用于指定要执行的定时器任务。

接下来,我们在线程执行任务期间,使用 this_thread::sleep_for 函数暂停当前线程 5 秒钟,最后,我们在程序结束之前调用了 stop 函数来停止定时器。

4.2 结合事件循环使用

在大多数情况下,定时器通常与 GUI 程序的事件循环功能一起使用。例如,以下演示如何使用户单击窗口后每隔 1 秒切换一次背景颜色。

int32_t bgColor = WHITE_COLOR;
Timer timer;

while (window.isOpen()) {
    render(bgColor); // 渲染窗口界面

    sf::Event event;
    while (window.pollEvent(event)) {
        switch (event.type) {
        case sf::Event::Closed:
            window.close();
            break;
        case sf::Event::MouseButtonPressed:
            bgColor = bgColor ^ 0x00ffffff; // 切换背景颜色
            timer.start(1000, [&bgColor]() {
                bgColor = bgColor ^ 0x00ffffff;
            });
            break;
        default:
            break;
        }
    }
}

在这个示例中,首先渲染窗口界面。在事件循环中,我们检查用户是否按下鼠标按钮。如果按下鼠标按钮,则切换背景颜色并设置颜色 bgColor 为新的背景颜色,同时使用 Timer 计时器并传入一个 lambda 表达式, 以便在 1 秒后重新切换并重绘目标颜色。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++11实现简易定时器的示例代码 - Python技术站

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

相关文章

  • C++示例详解Prim算法与优先队列

    C++示例详解Prim算法与优先队列 什么是Prim算法? Prim算法是一种经典的最小生成树算法,它可以用于求无向连通图的最小生成树。该算法以一个顶点开始,通过不断地向外扩张生成最小生成树,最终遍历图中所有节点,并且每次扩张的时候选择权值最小的边。 Prim算法的实现流程 选取一个起始节点开始。 初始化辅助数组,该数组用来记录图中每个节点是否已经被访问,以…

    C 2023年5月23日
    00
  • qq炫舞宠物天使之恋碎片c怎么得 天使碎片C获得方法推荐

    QQ炫舞宠物天使之恋碎片C的获得方法和推荐 QQ炫舞宠物天使之恋碎片C是一种宠物碎片,可以用于制作宠物,或者升级个人宠物等级。以下是获得该碎片的两种方法以及一些推荐。 方法一:购买宠物天使之恋组合礼包 在官方商城中有销售宠物天使之恋组合礼包,内含有宠物碎片C。购买该礼包可获得碎片并且获得其他的奖励。同时,购买礼包时要注意是否有活动优惠。 方法二:参加官方活动…

    C 2023年5月23日
    00
  • C语言实现飞机大战程序设计

    C语言实现飞机大战程序设计攻略 本文将介绍如何使用C语言编写一个基于控制台的飞机大战游戏。该游戏将在控制台内实现,通过键盘控制飞机移动与发射子弹,实现与敌机的战斗。 准备工作:学习C语言的基础知识 在开始编写游戏前,需要掌握一些基本的C语言知识,包括语法、变量、函数等。如果你是初学者,可以先通过一些C语言的教程、书籍或视频学习基础知识。 第一步:绘制游戏画面…

    C 2023年5月23日
    00
  • C语言示例讲解if else语句的用法

    C语言示例讲解if else语句的用法 介绍与概述 在 C 语言中,if…else 语句是一种非常有用的逻辑结构,可以基于条件来控制程序流程的执行。它的基本语法如下所示: if (condition) { // 当条件为真时执行的代码 } else { // 当条件为假时执行的代码 } 其中,condition 是要进行判断的条件表达式,当条件表达式的值…

    C 2023年5月23日
    00
  • C++如何将二叉搜索树转换成双向循环链表(双指针或数组)

    将二叉搜索树转换成双向循环链表是一道比较经典的算法题,本文将对该算法进行完整讲解。 算法思路 我们可以将该问题划分成多个子问题:- 将左子树转换为双向循环链表,并返回链表头和链表尾;- 将右子树转换为双向循环链表,并返回链表头和链表尾;- 将当前节点插入左子树的链表尾,将左子树链表尾连接至当前节点;- 将当前节点插入右子树的链表头,将右子树链表头连接至当前节…

    C 2023年5月23日
    00
  • Lua教程(六):编译执行与错误

    Lua教程(六):编译执行与错误 Lua是一门解释型脚本语言,它的源代码需要经过编译才能在计算机上运行。本篇教程将介绍如何编译和执行Lua代码,以及如何处理代码中的错误。 编译执行Lua代码 Lua交互模式 在安装了Lua解释器后,打开终端或命令行,输入lua命令即可进入Lua交互模式。在交互模式下,可以逐行输入Lua代码并立即执行,也可以使用dofile或…

    C 2023年5月23日
    00
  • C++ 如何将Lambda转换成函数指针

    要将 C++ 中的 Lambda 表达式转换成函数指针,需要使用到一种特殊的转换方式,也就是将 Lambda 表达式转换成函数指针类型。 Lambda 表达式是一种可调用对象,它往往是为了满足某些特定的需求而创建的,而将 Lambda 表达式转换成函数指针则可以让它更加灵活地应用于程序的不同场景。下面是具体的转换攻略: 步骤1:定义 Lambda 表达式 首…

    C 2023年5月23日
    00
  • mysql(5.6及以下)解析json的方法实例详解

    mysql(5.6及以下)解析json的方法实例详解 背景 在以往的开发中,我们通常使用MySQL来存储数据,然而在数据中存在着大量的json类型的数据,如何快速、便捷的解析json数据就变得尤为重要。本文将介绍Mysql(5.6及以下)中解析json类型数据的方法及实例。 操作步骤 使用JSON_EXTRACT()方法解析json数据 JSON_EXTRA…

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