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++详解如何实现动态数组

    C++中实现动态数组有多种方式,常见的包括使用指针和STL容器。下面简要介绍一下这两种实现方式。 使用指针实现动态数组 申请动态数组空间 在C++中,我们可以使用new关键字来动态申请内存空间,然后使用指针来存储这个内存地址。例如,我们可以使用以下代码申请一个长度为10的整型动态数组: int* arr = new int[10]; 访问动态数组元素 当我们…

    C 2023年5月23日
    00
  • 简单掌握Linux系统中fork()函数创建子进程的用法

    下面我来为你详细讲解如何简单掌握Linux系统中fork()函数创建子进程的用法。 什么是fork()函数 fork()函数是Linux系统中一个创建子进程的系统调用,它能够创建一个新的进程并复制一份父进程的所有内存空间和资源,然后两个进程在fork()函数的返回处继续执行。子进程与父进程之间是独立的进程,它们之间的变量、指针和数据都相互独立,互不影响。 如…

    C 2023年5月24日
    00
  • C++实现图书管理系统最新版

    C++实现图书管理系统最新版 简介 本文将会详细讲解如何使用C++实现一个简单的图书管理系统。此系统模拟了图书馆的基本管理功能,具有管理图书、借阅图书、归还图书等功能。 实现步骤 创建一个C++项目,并在项目中新建一个名为 book.h 的头文件。 在 book.h 中定义一个 Book 结构体,包含以下属性:* int book_id:图书编号* stri…

    C 2023年5月23日
    00
  • 求斐波那契(Fibonacci)数列通项的七种实现方法

    求斐波那契数列通项的七种实现方法 方法一:递归 斐波那契数列的递推公式为:F(n) = F(n-1) + F(n-2),为了求得第 n 个斐波那契数,可以通过递归求解,但是递归实现时间复杂度为 O(2^n),随着 n 的增大,运行效率会非常低下。 def fib_recursion(n): if n <= 1: return n return fib_…

    C 2023年5月22日
    00
  • IOS中Json解析实例方法详解(四种方法)

    这里给您详细讲解“IOS中Json解析实例方法详解(四种方法)”的完整攻略。 简介 iOS应用中,我们有时需要从服务器端获取JSON数据,这时我们就需要对JSON数据进行解析。本篇文章将详细介绍iOS中JSON解析的四种方法。 方法一:NSJSONSerialization NSJSONSerialization是iOS 5.0之后提供的解析JSON数据的类…

    C 2023年5月23日
    00
  • c++中的内联函数inline用法实例

    C++中的内联函数inline用法实例 什么是内联函数? 在程序中,当函数被调用时,程序会跳转到函数代码所在的内存地址执行函数代码,执行完毕之后再跳转回调用函数的位置。但是,如果函数的代码非常简单,每次调用时程序执行这个跳转的过程所花费的开销比函数代码还要大,这时就需要使用内联函数。 内联函数就是把函数的代码直接嵌入到调用函数的地方,而不是跳转到函数所在的内…

    C 2023年5月23日
    00
  • 一次因信号量引发的tomcat异常退出解决

    下面是一次因信号量引发的Tomcat异常退出解决的完整攻略: 背景 在使用Tomcat时,有时候可能会因为进程无法获取到信号量而导致Tomcat异常退出。这种问题通常会在并发量较大的情况下出现。 解决方法 解决这种问题的方法是通过增加操作系统的信号量来提高并发量。下面是具体的操作步骤: 查看当前信号量的情况: ipcs -ls 在这个命令中,参数 -l 表示…

    C 2023年5月22日
    00
  • C++产生随机数的实现代码

    以下是关于C++产生随机数的实现攻略: 1. 使用标准库函数 C++中内置了产生随机数的函数:std::rand()。该函数需要在使用前先调用srand()函数进行初始化。srand()函数可以接受一个参数,该参数为种子值,通常使用代表当前系统时间的值或者当前进程ID等较为常见。 示例代码: #include <iostream> #includ…

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