关键词:
程序中实现延时有很多种办法,但是有些不建议用。比如还在用sleep()或者空转计数的方式延时?要么移植性不好,要么不够精确且效率太低。这里总结下现代c++中推荐的一种实现精确延时的方法。
之前的一些用法
粗暴空转
long wait = 0;
while(wait < 1000)
wait++;
这种非常不建议用,懒人做法。不够精确且换种环境系统处理速度不一样可能就是bug来源。
使用sleep()
#include <windows.h>
#include <iostream>
using namespace std;
int main()
cout <<"a";
// 先输出a,再等2秒(2000毫秒),再输出a
Sleep(2000);
cout <<"a";
return 0;
一般的平台或系统环境都带sleep()函数,可以实现简单的延时。但是这种延时不能指望精确,且最小精度1ms都难以保证。而且这种用法也不能跨平台,Windows下是大写字母开头的Sleep(),单位为毫秒,linux下面是小写的sleep()。Linux下的sleep()函数是以秒为单位的,sleep(1)就是休眠1秒,想实现更短的休眠,linux下有usleep()函数。
使用计时函数clock()
clock() 函数是 C 标准库 time.h
中的一个函数, time.h
标准库中定义了各种涉及日期和时间的函数, 变量类型和宏. 其中, clock() 函数可以返回自程序开始执行到当前位置为止, 处理器走过的时钟打点数(即"ticks", 可以理解为"处理器时间").
每过千分之一秒(即 1 毫秒)则 clock() 函数的返回值加 1. 但是, 处理器的时钟打点数并不是一个人类可以直观感知的时间概念, 时钟打点数只描绘了该处理器在处理该问题时所耗费的"处理器时间". 为了能将获取到的时间转换成便于人类理解且具有普遍性的"时 分 秒"的计时方式, 我们需要引入一个常量,在 Windows下使用常量 CLOCKS_PER_SEC 来进行转换且 CLOCKS_PER_SEC=1000.
在linux环境CLOCKS_PER_SEC 的值被定义成 1000000.
void delay()
clock_t start_time;//, cur_time;
start_time = clock();//clock()返回当前时间
for (; (clock() - start_time) < 0.5 * CLOCKS_PER_SEC;);//延迟0.5秒
使用clock()函数也可以实现延时,通用性稍好些且能做到精确,但是也只能精确到1ms,常用它来测量某段代码的运行耗时用。
#include <time.h>
void test1()
clock_t start, stop;
/*
定义记录开始和结束时间的变量.
clock_t 是 clock() 函数的返回变量类型.
*/
double duration;
/*
记录函数运行时间
*/
start=clock();
printf("start=%d\\n",start);
for(int i = 0; i< 100000000; i++)
;
stop=clock();
printf("stop=%d\\n",stop);
duration=((double)(stop-start))/CLOCKS_PER_SEC;
//将时钟打点数转换成人类可以直观感知的时间秒数.
printf("CLOCKS_PER_SEC=%d\\n",CLOCKS_PER_SEC);
printf("duration=%f\\n",duration);
使用c++11之后的线程休眠函数
C++ 11之前并未提供专门的休眠函数。c语言的sleep、usleep其实都是系统提供的函数,不同的系统函数的功能还有些差异。从C++11开始,中C++标准库提供了专门的线程休眠函数,使得你的代码可以独立于不同的平台,sleep的时间间隔从纳秒到小时都有具体的定义。
比如我们想要一个线程休眠100ms:
#include <iostream>
#include <chrono>
#include <thread>
int main()
std::cout << "Hello waiter\\n" << std::flush;
auto start = std::chrono::high_resolution_clock::now();
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end-start;
std::cout << "Waited " << elapsed.count() << " ms\\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
推荐的用法
千呼万唤始出来,以下才是现在c++推荐的实现精确延时的用法。
#include <chrono>
void delay(int timeout_ms)
auto start = std::chrono::system_clock::now();
while (true)
auto duration =
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start).count();
if (duration > timeout_ms)
LOGGING_ERROR("timeout occurred,timeout %d ms", timeout_ms);
break;
引用
C / C++ 中的计时函数: clock()_荒原之梦网的博客-CSDN博客
std::chrono::high_resolution_clock简单测试 - 知乎
C++11 新的计时方法——std::chrono 大法好_一只牛_007的博客-CSDN博客
c++11 日期和时间工具-(std::chrono::steady_clock)(std::chrono::high_resolution_clock)_繁星璀璨G的博客-CSDN博客
android中实现延时执行操作的几种方法
参考技术A在这里记录一下几种实现延时执行操作的方法:1.使用线程的休眠实现延时操作2.使用TimerTask实现延时操作3.使用Handler的postDelayed方法实现延时操作推荐使用第三种 查看详情
unity中实现ui元素的响应区域精确判定(代码片段)
...c;所以不建议使用还有一种方法可以看这篇文章:Unity中实现自己的圆形Image组件_L的博客-CSDN博客使用Ray-Crossing算法去判断响应区域,但前提是UI元素必须是代码动态绘制出来的对于上面这种美术直接提供的PNG素材的响应... 查看详情
unity中实现ui元素的响应区域精确判定(代码片段)
...c;所以不建议使用还有一种方法可以看这篇文章:Unity中实现自己的圆形Image组件_L的博客-CSDN博客使用Ray-Crossing算法去判断响应区域,但前提是UI元素必须是代码动态绘制出来的对于上面这种美术直接提供的PNG素材的响应... 查看详情
在 C++ 中实现断言检查的最佳方法是啥?
】在C++中实现断言检查的最佳方法是啥?【英文标题】:WhatisthebestwayofimplementingassertioncheckinginC++?在C++中实现断言检查的最佳方法是什么?【发布时间】:2008-10-0718:21:18【问题描述】:我的意思是,我需要做什么才能在我的代码... 查看详情
windows批处理中实现延时的办法
五种方法可以实现批出里的延时,推荐使用方法一,该方法也是使用最多的.方法一用ping命令延迟(这是最简单而且是最常见的):@echooffecho"usepingtodelay"setSLEEP=ping127.0.0.1/necho%time%%SLEEP%4>nulecho%time%pause方法二还可以用for循环作延迟... 查看详情
如何在 C++ 模板容器中实现 erase() 方法
】如何在C++模板容器中实现erase()方法【英文标题】:Howtoimplementerase()methodinaC++templatecontainer【发布时间】:2015-05-0918:47:44【问题描述】:对于书本练习,我需要创建一个名为Vec的简单C++容器(模仿std::vector的容器)。但是,我在... 查看详情
在 Visual Studio 2015 解决方案中实现 C++ 模板的正确方法是啥?
】在VisualStudio2015解决方案中实现C++模板的正确方法是啥?【英文标题】:WhatisthecorrectwaytoimplementaC++templateinaVisualStudio2015solution?在VisualStudio2015解决方案中实现C++模板的正确方法是什么?【发布时间】:2016-10-1716:00:49【问题描述】... 查看详情
javascript在javascript中实现singleton模式的3种方法(代码片段)
在 C++ 聚合类中实现调用多路复用的优雅方式?
】在C++聚合类中实现调用多路复用的优雅方式?【英文标题】:ElegantwayofimplementingcallmultiplexinginaC++aggregateclass?【发布时间】:2011-08-2912:12:55【问题描述】:当多路复用对许多子对象的调用时,防止循环样板代码的优雅方法是什... 查看详情
windows批处理中实现延时的办法
windows批处理中实现延时的办法 五种方法可以实现批出里的延时,推荐使用方法一,该方法也是使用最多的. 方法一 用ping命令延迟(这是最简单而且是最常见的): @echo off echo "use ping to delay"&nb... 查看详情
如何在 C++ 中实现方法返回类似 Java 中的对象 [关闭]
】如何在C++中实现方法返回类似Java中的对象[关闭]【英文标题】:HowtoimplementamethodreturnsomethinglikeObject-in-JavainC++[closed]【发布时间】:2012-10-2902:36:32【问题描述】:我正在从Java背景学习C++,这是我刚刚遇到的一个问题:假设我有... 查看详情
[c++]c++中的延时方法总结
在windows上延时#include<iostream>#include<windows.h>usingnamespacestd;voidmain() //睡眠5秒再输出 Sleep(5000);//单位是毫秒 std::cout<<"over!"<<std::endl;在linux上#include<iostream>#include<unistd.h>usingnamespacestd;intmain() ... 查看详情
swift在uitextview(swift)中实现占位符的正确方法(代码片段)
python中实现可迭代对象的方法(代码片段)
...实例对象可以迭代,也就是可以使用for来遍历,需要在类中实现__iter__方法,需要实现__next__方法。classClassmates():def__init__(self):self.name=[]self.current_num=0defadd(self 查看详情
如何在 C++ 中实现接口? [复制]
】如何在C++中实现接口?[复制]【英文标题】:howtoimplementInterfacesinC++?[duplicate]【发布时间】:2012-04-0303:42:42【问题描述】:可能重复:PreferredwaytosimulateinterfacesinC++我很想知道C++中是否有接口,因为在Java中,设计模式的实现主要... 查看详情
在 C++ 中实现归并排序
】在C++中实现归并排序【英文标题】:implementingmergesortinC++【发布时间】:2012-08-1508:54:51【问题描述】:我研究过归并排序的理论,但对如何在C++中实现它一无所知。我的问题是,合并排序以递归方式创建数组。但是在实现的时... 查看详情
以下 C++ 代码中实现的 DCL(双重检查锁定)是不是是线程安全的?
】以下C++代码中实现的DCL(双重检查锁定)是不是是线程安全的?【英文标题】:IstheDCL(double-checkedlocking)implementedinthefollowingC++codethread-safe?以下C++代码中实现的DCL(双重检查锁定)是否是线程安全的?【发布时间】:2020-05-0812:57... 查看详情
[记录点滴]一个python中实现flatten的方法(代码片段)
之前如果想使用flatten,一般借助于numpy.ndarray.flatten。但是flatten只能适用于numpy对象,即array或者mat,普通的list列表不适用。最近找到一个轻便的办法如下:fromitertoolsimportchain#flattenprint(list(set(chain.from_iterable(["aaa","bbb&q... 查看详情