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

定时器timer是多线程编程中经常设计到的工具类

定时器的原理其实很简单:

  • 创建一个新线程
  • 在那个线程里等待
  • 等待指定时长后做任务

这里用C++11实现了一个简单易用的定时器,包含两种模式:

  • 周期性定时任务执行
  • 单次延时任务执行

timer.hpp

#ifndef _TIMER_H_
#define _TIMER_H_

#include <functional>
#include <chrono>
#include <thread>
#include <atomic>
#include <memory>
#include <mutex>
#include <condition_variable>

class Timer
{
public:
 Timer(): _expired(true), _try_to_expire(false)
 {}

 Timer(const Timer& timer)
 {
 _expired = timer._expired.load();
 _try_to_expire = timer._try_to_expire.load();
 }

 ~Timer()
 {
 stop();
 }

 void start(int interval, std::function<void()> task)
 {
 // is started, do not start again
 if (_expired == false)
  return;

 // start async timer, launch thread and wait in that thread
 _expired = false;
 std::thread([this, interval, task]() {
  while (!_try_to_expire)
  {
  // sleep every interval and do the task again and again until times up
  std::this_thread::sleep_for(std::chrono::milliseconds(interval));
  task();
  }

  {
  // timer be stopped, update the condition variable expired and wake main thread
  std::lock_guard<std::mutex> locker(_mutex);
  _expired = true;
  _expired_cond.notify_one();
  }
 }).detach();
 }

 void startOnce(int delay, std::function<void()> task)
 {
 std::thread([delay, task]() {
  std::this_thread::sleep_for(std::chrono::milliseconds(delay));
  task();
 }).detach();
 }

 void stop()
 {
 // do not stop again
 if (_expired)
  return;

 if (_try_to_expire)
  return;

 // wait until timer
 _try_to_expire = true; // change this bool value to make timer while loop stop
 {
  std::unique_lock<std::mutex> locker(_mutex);
  _expired_cond.wait(locker, [this] {return _expired == true; });

  // reset the timer
  if (_expired == true)
  _try_to_expire = false;
 }
 }

private:
 std::atomic<bool> _expired; // timer stopped status
 std::atomic<bool> _try_to_expire; // timer is in stop process
 std::mutex _mutex;
 std::condition_variable _expired_cond;
};

#endif // !_TIMER_H_

main.cpp

#include <iostream>
#include "timer.hpp"

void func1()
{
 std::cout << "trigger func1" << std::endl;
}

void func2(int x)
{
 std::cout << "trigger func2, x: " << x << std::endl;
}

int main(int argc, char* argv[])
{
 Timer timer;

 // execute task every timer interval
 std::cout << "--- start period timer ----" << std::endl;
 timer.start(1000, std::bind(func2, 3));
 std::this_thread::sleep_for(std::chrono::milliseconds(5000));
 timer.stop();
 std::cout << "--- stop period timer ----" << std::endl;

  // execute task once after delay
 std::cout << "--- start one shot timer ----" << std::endl;
 timer.startOnce(1000, func1);
 std::cout << "--- stop one shot timer ----" << std::endl;

 getchar();
 return 0;
}

运行结果

--- start period timer ----
trigger func2, x: 3
trigger func2, x: 3
trigger func2, x: 3
trigger func2, x: 3
trigger func2, x: 3
--- stop period timer ----
--- start one shot timer ----
--- stop one shot timer ----
trigger func1

到此这篇关于C++11实现简易定时器的示例代码的文章就介绍到这了,更多相关C++11 定时器 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++控制台用定时器实例代码

    本文研究的主要是C++控制台用定时器的相关实例,具体如下. Timer在MFC程序中的使用 在MFC中有一个很好用的定时器函数. 使用SetTimer()进行设置定时器 使用KillTimer()关闭定时器 在OnTimer()函数中,响应WM_TIMER这个消息,也就是定时器的处理函数. 源代码 #define TIMER_UDP_QFX 3//定时器的ID int Period = 1000;//1000ms的定时器 //设置一个定时器 SetTimer(TIMER_UDP_QFX, Per

  • C++定时器Timer在项目中的使用方法

    前言 本文主要给大家介绍了关于C++定时器Timer在项目使用的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 1.情况说明 由于最近要在项目里做弹出弹幕,要求是弹出1秒后消失,一开始我使用空循环进行计时,发现执行到这段代码CPU占用率上升十几个百分点,后来改成定时器实现,发现CPU表现正常. 2.空循环实现 ShowWindow(true); time_t start_time = GetTickCount(); time_t now_time = start_tim

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

    定时器timer是多线程编程中经常设计到的工具类 定时器的原理其实很简单: 创建一个新线程 在那个线程里等待 等待指定时长后做任务 这里用C++11实现了一个简单易用的定时器,包含两种模式: 周期性定时任务执行 单次延时任务执行 timer.hpp #ifndef _TIMER_H_ #define _TIMER_H_ #include <functional> #include <chrono> #include <thread> #include <atomi

  • Qt实现简易计时器的示例代码

    目录 一.项目介绍 二.项目基本配置 三.UI界面设计 四.主程序实现 4.1 mainwindow.h头文件 4.2 mainwindow.cpp源文件 五.效果演示 一.项目介绍 计时器实现四个功能:开始计时.停止计时.暂停计时以及打点.当点击暂停时,开始按钮和停止按钮无法点击,此时暂停按钮变为继续.当点击停止时,开始按钮和暂停按钮无法点击,此时停止按钮变为清零. 二.项目基本配置 新建一个Mainwindow界面.基本配置与其他Qt项目类似,这里不过多介绍. 三.UI界面设计 UI界面如下

  • Python实现简易计算器的示例代码

    目录 实现流程 计算器布局 计算机执行 代码展示 运行展示 上次我用我学习的python做一个简易的计算器,我对计算器进行了,更改优化,变成了一个真正的计算器 实现流程 1.计算机布局 2.计算机执行 首先导入模块: Tkinter 作为 Python GUI 开发工具之一,它具有 GUI 软件包的必备的常用功能.比如,它提供了十多种不同类型的窗口控件.窗口布局管理器.事件处理机制等,加之其开发效率高.代码简洁易读 import tkinter as tk #Python3标准安装包中自带tki

  • 利用Python实现简易计算器的示例代码

    目录 实现流程 代码实现 定义函数 输入值 判断运算 全部代码展示 运行展示 最近学习了字符串,运算符,条件语句,循环语句,我在想可以用我最近学的东西做什么? 看到运算我就想到了可以做一个简易的计算器. 实现流程 1.定义函数 2.请用户选择运算方法 3.请用户输入要运算的两个数 4.运算出结果 代码实现 定义加减乘除四种函数,在后续的运算中调用这四个函数输出结果. 定义加减乘除四种运算的函数 定义函数要用def 首先定义加法函数add在里面传入参数x,y   返回值X加y 定义subtract

  • Spring Boot使用过滤器和拦截器分别实现REST接口简易安全认证示例代码详解

    本文通过一个简易安全认证示例的开发实践,理解过滤器和拦截器的工作原理. 很多文章都将过滤器(Filter).拦截器(Interceptor)和监听器(Listener)这三者和Spring关联起来讲解,并认为过滤器(Filter).拦截器(Interceptor)和监听器(Listener)是Spring提供的应用广泛的组件功能. 但是严格来说,过滤器和监听器属于Servlet范畴的API,和Spring没什么关系. 因为过滤器继承自javax.servlet.Filter接口,监听器继承自ja

  • 利用jQuery+localStorage实现一个简易的计时器示例代码

    前言 在HTML5中,新加入了一个localStorage特性,这个特性主要是用来作为本地存储来使用的,解决了cookie存储空间不足的问题(cookie中每条cookie的存储空间为4k),localStorage中一般浏览器支持的是5M大小,这个在不同的浏览器中localStorage会有所不同. 本文主要介绍了关于jQuery+localStorage实现简易计时器的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 原型 需求 1.关闭浏览器时时间继续运行 2.刷

  • vue + socket.io实现一个简易聊天室示例代码

    vue + vuex + elementUi + socket.io实现一个简易的在线聊天室,提高自己在对vue系列在项目中应用的深度.因为学会一个库或者框架容易,但要结合项目使用一个库或框架就不是那么容易了.功能虽然不多,但还是有收获.设计和实现思路较为拙劣,恳请各位道友指正. 可以达到的需求 能查看在线用户列表 能发送和接受消息 使用到的框架和库 socket.io做为实时通讯基础 vuex/vue:客户端Ui层使用 Element-ui:客户端Ui组件 类文件关系图 服务端: 客户端: 服

  • Spring整合Quartz实现动态定时器的示例代码

    一.版本说明 spring3.1以下的版本必须使用quartz1.x系列,3.1以上的版本才支持quartz 2.x,不然会出错. 原因:spring对于quartz的支持实现,org.springframework.scheduling.quartz.CronTriggerBean继承了org.quartz.CronTrigger,在quartz1.x系列中org.quartz.CronTrigger是个类,而在quartz2.x系列中org.quartz.CronTrigger变成了接口,从

  • JS实现简易刻度时钟示例代码

    如图所示,利用JS实现简易的刻度时钟: 原理如下:利用60等份的li进行布局,li两两之间的间隔为6deg,把基点定在圆心上,使得li圆形分布.然后另外设置三条针线的样式的位置,基点同样定在圆心上,然后秒针每秒动6deg,分针每秒动1/60deg,时针每秒动1/3600deg. 布局代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></ti

  • Matlab实现简易纪念碑谷游戏的示例代码

    按上下左右键(↑↓←→)移动物块 按AD键转动视角 游戏效果:如图所示原本无法通过的路径经过视角调整即可通过 完整代码 function maze4 global maze; global GUI; global role; GUI.fig=figure('units','pixels',... 'position',[350 100 500 500],... 'Numbertitle','off',... 'name','maze',... 'Color',[0 0 0],... 'resiz

随机推荐