现代c++中实现精确延时方法总结(代码片段)

特立独行的猫a 特立独行的猫a     2022-12-14     493

关键词:

程序中实现延时有很多种办法,但是有些不建议用。比如还在用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新特征8 - 时钟与计时器 - 知乎

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... 查看详情