• 现代c++中实现精确延时方法总结


    程序中实现延时有很多种办法,但是有些不建议用。比如还在用sleep()或者空转计数的方式延时?要么移植性不好,要么不够精确且效率太低。这里总结下现代c++中推荐的一种实现精确延时的方法。

     之前的一些用法 

    粗暴空转

    1. long wait = 0;
    2. while(wait < 1000)
    3. wait++;

    这种非常不建议用,懒人做法。不够精确且换种环境系统处理速度不一样可能就是bug来源。

    使用sleep()

    1. #include
    2. #include
    3. using namespace std;
    4. int main()
    5. {
    6. cout <<"a";
    7. // 先输出a,再等2秒(2000毫秒),再输出a
    8. Sleep(2000);
    9. cout <<"a";
    10. return 0;
    11. }

    一般的平台或系统环境都带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.

    1. void delay()
    2. {
    3. clock_t start_time;//, cur_time;
    4. start_time = clock();//clock()返回当前时间
    5. for (; (clock() - start_time) < 0.5 * CLOCKS_PER_SEC;);//延迟0.5秒
    6. }

    使用clock()函数也可以实现延时,通用性稍好些且能做到精确,但是也只能精确到1ms,常用它来测量某段代码的运行耗时用。

    1. #include
    2. void test1(){
    3. clock_t start, stop;
    4. /*
    5. 定义记录开始和结束时间的变量.
    6. clock_t 是 clock() 函数的返回变量类型.
    7. */
    8. double duration;
    9. /*
    10. 记录函数运行时间
    11. */
    12. start=clock();
    13. printf("start=%d\n",start);
    14. for(int i = 0; i< 100000000; i++){
    15. ;
    16. }
    17. stop=clock();
    18. printf("stop=%d\n",stop);
    19. duration=((double)(stop-start))/CLOCKS_PER_SEC;
    20. //将时钟打点数转换成人类可以直观感知的时间秒数.
    21. printf("CLOCKS_PER_SEC=%d\n",CLOCKS_PER_SEC);
    22. printf("duration=%f\n",duration);
    23. }

    使用c++11之后的线程休眠函数

    C++ 11之前并未提供专门的休眠函数。c语言的sleep、usleep其实都是系统提供的函数,不同的系统函数的功能还有些差异。从C++11开始,中C++标准库提供了专门的线程休眠函数,使得你的代码可以独立于不同的平台,sleep的时间间隔从纳秒到小时都有具体的定义。

    比如我们想要一个线程休眠100ms:

    1. #include
    2. #include
    3. #include
    4. int main() {
    5. std::cout << "Hello waiter\n" << std::flush;
    6. auto start = std::chrono::high_resolution_clock::now();
    7. std::this_thread::sleep_for(std::chrono::milliseconds(2000));
    8. auto end = std::chrono::high_resolution_clock::now();
    9. std::chrono::duration<double, std::milli> elapsed = end-start;
    10. std::cout << "Waited " << elapsed.count() << " ms\n";
    11. std::this_thread::sleep_for(std::chrono::milliseconds(100));
    12. }

    推荐的用法

    千呼万唤始出来,以下才是现在c++推荐的实现精确延时的用法。

    1. #include
    2. void delay(int timeout_ms)
    3. {
    4. auto start = std::chrono::system_clock::now();
    5. while (true)
    6. {
    7. auto duration =
    8. std::chrono::duration_cast(std::chrono::system_clock::now() - start).count();
    9. if (duration > timeout_ms)
    10. {
    11. LOGGING_ERROR("timeout occurred,timeout %d ms", timeout_ms);
    12. break;
    13. }
    14. }

    引用

    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博客

  • 相关阅读:
    Vue业务组件封装(二)Form表单
    局域网内共享文件夹局域网通信等遇到连不上的问题
    AcWing 275. 传纸条
    鸿蒙应用开发-初见:入门知识、应用模型
    循环神经网络RNN、RNNCell、GRUCell
    案例题真题-数据库系统
    3.1_2 覆盖与交换
    使用docker创建minio镜像并上传文件,提供demo
    java集合框架综述
    vue 组件基础
  • 原文地址:https://blog.csdn.net/qq8864/article/details/127932930