跟我学c++中级篇—c++11时间库实现定时器和延时

一、C++11时间库

先简单介绍一下C++11中有三类时钟:
1、system_clock:可以理解为壁钟,可调整(向前或向后),是系统时间。它可以 与C语言风格的时间进行映射。
2、steady_clock:类似于秒表的单调时钟,只可增长不能修改,最适合进行时间间隔的测量。
3、high_resolution_clock:高精度的时钟(最小计次周期),不可以修改的,可以将其看做 steady_clock或system_clock 的高精度版的别名(gcc 的 libstdc++ 它是 system_clock ,对于 MSVC 它是 steady_clock ,而对于 clang 的 libc++ 它取决于配置)。对时长度量使用 steady_clock ,对壁钟时间使用 system_clock
此处不对C++11中的时钟进行详细分析,只关心几种应用方式,下面逐一说明分析。

二、应用的介绍

这里面有一疑问的可以看一下下面的程序,对sleep_for和sleep_until的使用是延时和定时器的主要方式,它们都是延时,一个到点,一个停止一段。有的资料说sleep_for会导致整个进程的所有线程阻塞,但在标准文档写的是当前线程阻塞,下面的代码就可以验证是哪种。

#include <chrono>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <thread>
#include <unistd.h>using namespace std;void for_thread() {this_thread::sleep_for(chrono::seconds(6));cout << "sleep_for:" << this_thread::get_id() << " is  start" << endl;
}void loop_thread() {//sleep(1);for (int i = 0; i < 10; i++) {cout << "loop thread:" << this_thread::get_id() << "cur value: " << i << endl;}
}
void until_thread() {using std::chrono::operator""s;chrono::time_point t = std::chrono::steady_clock::now() + 3s;this_thread::sleep_until(t);cout << "sleep_until:" << this_thread::get_id() << "is  start" << endl;
}int main() {thread t1(for_thread);thread t2(loop_thread);thread t3(until_thread);t2.join();t1.join();t3.join();return 0;
}

很多情况都需要实践操作一下,即使是操作的有问题,也可以 更好的理解问题本身和应用库的特点。

三、定时器应用

1、做定时器

void timerLoop() {bool Continue = true;while (Continue) {Continue = timerCallback();//回调函数,也就是定时器定时触发的函数if (Continue) {m_timer.sleepUntil();//时间间隔}}
}
//间隔设置用下而把 方法
double freq = 30.0;//此值可动态调整
duration = duration_cast<std::chrono::duration<long, std::micro>>(microseconds((long long)round(1e6 / freq)));
//可以理解为时间轮的槽的长度
void sleepUntil() {if (Done) {clock::time_point nextSlot = begin + duration;// sleepstd::this_thread::sleep_until(nextSlot);} else {Done = true;}begin = std::chrono::high_resolution_clock::now();
}

最初在学习定时器时,就不断看到说定时器其实就是一个独立的线程,现在自己实现一把,就更明白底层的实现了。原理基本都是类似的,重点在于两个,一个是写得要安全;另外一个是适应性要好。

2、延时(阻塞调用)
如果用在一种和需要阻塞一段时间才能拿到结果的API调用时,这种方法就有用了,以前好多人都是用死循环(硬件嵌入式比较多),但这种可能会使整个进程被占用。但在上层一般会用回调或者事件等方式来处理。不过总有一些情况需要延时,所以就可以 用这种来实现。如上面的函数:

void until_other() {std::chrono::time_point<std::chrono::steady_clock> now;now = std::chrono::steady_clock::now();std::this_thread::sleep_until(now + std::chrono::milliseconds(1000)+ std::chrono::microseconds(100));cout << "sleep_until_other:" << this_thread::get_id() << "is  start" << endl;
}

sleep_for比较简单,就不举例了。

3、计时
先看一下传统的测量耗时的方法

  struct timeval t1, t2;double timeuse;gettimeofday(&t1, NULL);//此处调用函数,用来测试时间gettimeofday(&t2, NULL);timeuse = t2.tv_sec - t1.tv_sec + (t2.tv_usec - t1.tv_usec) / 1000000.0;printf("readmeme Use Time:%f\n", timeuse);

再看一个用C++11时间库的:

#include <iostream>
#include <vector>
#include <numeric>
#include <chrono>volatile int sink;
int main()
{for (auto size = 1ull; size < 1000000000ull; size *= 100) {// 记录开始时间auto start = std::chrono::high_resolution_clock::now();// 做一些工作std::vector<int> v(size, 42);sink = std::accumulate(v.begin(), v.end(), 0u); // 确保其副效应// 记录结束时间auto end = std::chrono::high_resolution_clock::now();std::chrono::duration<double> diff = end-start;std::cout << "Time to fill and iterate a vector of "<< size << " ints : " << diff.count() << " s\n";}
}

还有一些细小的应用大家可以 在实际用到查一下文档即可。

四、总结

在C++11中利用时间库加线程就可以比较轻松的实现一个跨平台的定时器。这比在Linux的其它定时器的实现既简单又方便,精度也可以自己确定,这在一般的通用场合就足够了。简单就是王道,这个是无法比拟的。
最近总是有些想法想说一说。现在是知识爆炸的年代,许多技术知识在网上是可以很容易搜到的。但这些知识,有大牛给出的,有小牛给的,有经验丰富的开发者给的,更多的是一些应用者,甚至还有一些是初学者,把一些掌握的问题解法和知识心得发表到网上。这些技术或者解决技术难题的方法,从整体上看,相当多都只是某一方面上的,也可以说是很片面的。对不同的人群来说,可能这些知识所给予的心得各有不同。但从不同的角度来看,可能一些受众是初学者的,大牛们的文章反而短时间内不好消化吸收。学习终归是从点突破到线发展,最后到面扩展,到最终生成一个立体的知识球体也就是个人的认知体系,也是网上说的知识蚕茧。
有的人学习可能会是不断的打破这个茧,更多的人反而是强化这个茧。这就是牛人和非牛人的区别。说这么多是什么 意思呢?网上的知识被个体搜索到后,要有分辨能力,哪些能为我所用,哪些不能,哪些是正确的,哪些是错误的,哪些是片面的。网上的知识,很多是提供思路和灵感,不是说拷贝过来就用。要善于进行拿来主义,而不是僵化的拿来主义。要有哲学上否定之否定的思想,不断的总结和升华自己的知识体系,打破固有的知识牢笼或者说知识蚕茧。
学习永远在路上,变化才是永恒!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/66056.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows下Git Bash调用rsync

rsync 提供了补充只需要在git安装目录下放入对应的文件即可。 需要将这个三个文件放到git的bin目录下 如果是默认安装路径是如下&#xff1a; C:\Program Files\Git\usr\bin 然后大功告成。

【Vue2】 axios库

网络请求库-axios库 认识Axios库为什么选择Axios库安装Axios axios发送请求常见的配置选项简单请求可以给Axios设置公共的基础配置发送多个请求 axios创建实例为什么要创建axios的实例 axios的拦截器请求拦截器响应拦截器 axios请求封装 认识Axios库 为什么选择Axios库 在游览…

105. 从前序与中序遍历序列构造二叉树

给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 思路&#xff1a;题目给出了先序遍历和中序遍历的结果&#xff0c;因为先序遍历遵循根–>左–>…

21 自定义miniweb框架|闭包装饰器|log输出

文章目录 前情知识介绍WSIG-miniWeb框架服务器动态资源请求浏览器请求动态页面的全流程WSGIWSGI接口的定义 静态服务器回顾以及改造web 服务器 和 逻辑处理代码 分离 web动态服务器的基本实现带参数的web动态服务器 闭包装饰器闭包闭包的基础使用函数、匿名函数、闭包、对象修改…

python相关

1、更改用户名之后&#xff0c;C盘下的文件夹下名称没有改&#xff1f;这样设置 https://blog.csdn.net/qq_56088882/article/details/127470766 2、安装python和pycharm 链接 3、vscod中import requests出错&#xff1a;亲测有效&#xff1a; 链接

【Nginx21】Nginx学习:FastCGI模块(三)缓冲区与响应头

Nginx学习&#xff1a;FastCGI模块&#xff08;三&#xff09;缓冲区与响应头 缓存相关的内容占了 FastCGI 模块将近一小半的内容&#xff0c;当然&#xff0c;用过的人可能不多。而今天的内容说实话&#xff0c;我平常也没怎么用过。第一个是缓冲区相关的知识&#xff0c;其实…

Nat. Commun.2023 | AI-Bind+:提高蛋白质配体结合预测的通用性

论文标题&#xff1a;Improving the generalizability of protein-ligand binding predictions with AI-Bind 论文地址&#xff1a;Improving the generalizability of protein-ligand binding predictions with AI-Bind | Nature Communications 代码&#xff1a; Barabasi…

华为数通方向HCIP-DataCom H12-821题库(单选题:181-200)

第181题 某管理员需要创建AS Path过滤器(ip as-path-iter),允许AS_Path中包含65001的路由通过,那么以下哪一项配置是正确的? A、​​ip as-path-filter 1 permit 65001​​ B、​​ip as-path-filter 1 permit "65001​​ C、​​ip as-path-filter 1 permit *6500…

wxWidgets从空项目开始Hello World

前文回顾 接上篇&#xff0c;已经是在CodeBlocks20.03配置了wxWidgets3.0.5&#xff0c;并且能够通过项目创建导航创建一个新的工程&#xff0c;并且成功运行。 那么上一个是通过CodeBlocks的模板创建的&#xff0c;一进去就已经是2个头文件2个cpp文件&#xff0c;总是感觉缺…

Pygame中Trivia游戏解析6-3

3.3 Trivia类的show_question()函数 Trivia类的show_question()函数的作用是显示题目。主要包括显示题目框架、显示题目内容和显示题目选项等三部分。 3.3.1 显示题目的框架 在show_question()函数中&#xff0c;通过以下代码显示题目的框架。 print_text(font1, 210, 5, &q…

docker-compose 部署nacos 整合 postgresql 为DB

标题docker-compose 部署nacos 整合 postgresql 为DB 前提&#xff1a; 已经安装好postgresql数据库 先创建好一个数据库 nacos&#xff0c;执行以下sql: /** Copyright 1999-2018 Alibaba Group Holding Ltd.** Licensed under the Apache License, Version 2.0 (the "…

二进制转换16进制 快速心算

1111 1110 ---> 0xFE 1111 为 8 4 2 1 ---> 8 4 2 1 15 --> 16进制表示为F1110 为 8 4 2 0 ---> 8 4 2 0 14 --> 16进制表示为E

Ubuntu本地快速搭建web小游戏网站,公网用户远程访问【内网穿透】

文章目录 前言1. 本地环境服务搭建2. 局域网测试访问3. 内网穿透3.1 ubuntu本地安装cpolar内网穿透3.2 创建隧道3.3 测试公网访问 4. 配置固定二级子域名4.1 保留一个二级子域名4.2 配置二级子域名4.3 测试访问公网固定二级子域名 前言 网&#xff1a;我们通常说的是互联网&am…

win10 查看指定进程名的端口号

在 Windows 10 的任务管理器中也可以查看端口号。请按下面的步骤操作&#xff1a; 打开任务管理器&#xff0c;可以通过按下快捷键 CtrlShiftEsc 或者右键点击任务栏后选择任务管理器来打开。点击“性能”选项卡&#xff0c;然后点击左侧的“打开资源监视器”。在资源监视器中…

WebSocket(一)

一.什么是WebSocket 【1】WebSocket是一种协议&#xff0c;设计用于提供低延迟&#xff0c;全双工和长期运行的连接。 全双工&#xff1a;通信的两个参与方可以同时发送和接收数据&#xff0c;不需要等待对方的响应或传输完成。 【2】比较 传统通信&#xff08;http协议&am…

【LeetCode】1654:到家的最少跳跃次数的解题思路 关于力扣无法return的BUG的讨论

文章目录 一、题目二、题解与代码三、神奇的BUG3.1 无法执行的 return 和 break 语句3.2 通过另一个 break 解决 一、题目 有一只跳蚤的家在数轴上的位置 x 处。请你帮助它从位置 0 出发&#xff0c;到达它的家。 跳蚤跳跃的规则如下&#xff1a; 它可以 往前 跳恰好 a 个位…

java.sql.SQLException: com.mysql.cj.jdbc.Driver

这篇文章分享一下Springboot整合Elasticsearch时遇到的一个问题&#xff0c;项目正常启动&#xff0c;但是查询数据库的时候发生了一个异常java.sql.SQLException: com.mysql.cj.jdbc.Driver java.sql.SQLException: com.mysql.cj.jdbc.Driverat com.alibaba.druid.util.JdbcU…

软件测试/测试开发丨Pytest和Allure报告 学习笔记

点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接&#xff1a;https://ceshiren.com/t/topic/26755 Pytest 命名规则 类型规则文件test_开头 或者 _test 结尾类Test 开头方法/函数test_开头注意&#xff1a;测试类中不可以添加__init__构造函数 注…

JS虚拟机JS加密技术:优缺点及案例研究

JS虚拟机JS加密技术&#xff1a;优缺点及案例研究 JS虚拟机是一种用JS语法实现的模拟虚拟机逻辑执行的代码&#xff0c;以执行JS代码的技术。它提供了一种将JS代码编译成二进制指令集的方法&#xff0c;并模拟执行这些指令。本文将介绍jsvmp技术的优缺点&#xff0c;并提供一些…

CLR Via 读书笔记

CLR Via 读书笔记 第四章 类型基础 记录C#学习过程中的一些语法知识 ——2023.9.3 第四章 类型基础 点击跳转