zoukankan      html  css  js  c++  java
  • 关于c++中sleep_for函数的总结分析

    大家好,最近我在工作当中遇到了一个函数,就是c++中的sleep_for函数,说实话,这还真是我第一次见到这个函数,所以我就花了点时间研究了一下这个函数,现在想总结一下分享给大家。

      一、sleep_for函数的简介

      二、sleep_for函数用到的情景

      三、sleep_for函数,sleep函数以及yield函数三者的区别

      四、关于c++中chrono函数的使用

      五、关于c++中时间的获取方法

      一、sleep_for函数的简介

        先简单说一下sleep_for这个函数的情况。

        1、这个函数是一个线程函数,换句话说他的作用域只作用于当前线程,因此,包含它的库也就是thread库。

             2、这个函数的原型为

             sleep_for(const chrono::duration<_Rep, _Period>& __rtime)(关于chrono的部分我们待会再说,我们只要知道这是个时间间隔)

          3、这个函数要实现的目的就是线程阻塞,换句话说就是要让当前的线程休眠一段时间(具体时间就是我们传进去的参数),而其他进程不休息。

        最后举一个使用例子:std::this_thread::sleep_for(std::chrono::miliseconds(50))   //表示让该线程休眠50ms

      二、sleep_for用到的场景

        这里说一下我们为什么要用sleep_for,是这样的,我们这个代码中要发给底层硬件发送一条指令,我们知道硬件的处理速度是有一定时间的,所以为了不影响后续的代码的运行,所以需要

        做一个线程阻塞,保证其在这段时间内硬件处理完毕。

      三、关于sleep_for,sleep以及yield函数三者的区别 

        关于sleep_for,它还有一个类似的函数,叫yield,他的作用域,参数和sleep_for是一样的,它的函数原型是这样的:

          std::this_thread::yield: 当前线程放弃执行,操作系统调度另一线程继续执行。即当前线程将未使用完的“CPU时间片”让给其他线程使用,等其他线程使用完后再与其他线程一起竞争"CPU"。

        另外我们在系统中还有一个阻塞函数sleep函数,所以我们说一说三者的区别。

        我们先来说sleep函数,我们有两点要说明:

          1、sleep函数是系统函数,换句话说它不需要c++11支持,只要有编译器就能找到这个函数。

          2、sleep函数是进程阻塞函数,换句话说一旦调用这个函数,当前进程当中所有的线程全部阻塞。

        接着我们说其他两个函数:我们来看一下代码:

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        int n=0;
        std::thread t1(function1, std::ref(n));
        std::thread t2(function2, n);
        t1.join();
        t2.join();
        w.show();
    
    
        return a.exec();
    }
    
    

     

    void function1(int &n)
    {
        while (true) {
            std::this_thread::sleep_for(std::chrono::seconds(1));
            n++;
            if (n==10) {
                mux.lock();
                g_flag = true;
                mux.unlock();
    
    
            } else if(n == 15) {
                mux.lock();
                // std::this_thread::sleep_for(std::chrono::seconds(5));
                mux.unlock();
    
    
            }
            else if (n == 20) {
                mux.lock();
                g_flag = false;
                mux.unlock();
            } else if (n == 30) {
                mux.lock();
                g_flag = true;
                mux.unlock();
            }
            else {
                std::cout<<"F1 is:"<<n<<std::endl;
            }
        }
    }

    void function2(int n)
    {
        while(true) {
            std::this_thread::sleep_for(std::chrono::seconds(1));
            // std::this_thread::yield();
          n++;
            std::cout<<"F2 n: "<<n<<std::endl;
            mux.lock();
            bool flag = g_flag;
            mux.unlock();
            if (flag) {
            } else {
    
    
            }
        }
    }

    这里有两个线程,依次打印n的值,我们首先是不加yield语句打出来的结果

     看到了吗?两个函数的执行过程是随机的,这是因为CPU时间片调度算法本身就是随机的。

    接下来我们看一下加上yield的效果。

     这个效果是是什么呢?F1永远在F2前面,另外,F2中的n也在不断增长

    好了,到这里我们可以总结一下yield函数了,这个函数要注意两点:

    1、std::this_thread::yield(); 是将当前线程所抢到的CPU”时间片A”让渡给其他线程(其他线程会争抢”时间片A”,
    等到其他线程使用完”时间片A”后, 再由操作系统调度, 当前线程再和其他线程一起开始抢CPU时间片.

    就是说第一,遇到这个函数会优先让其他线程执行,第二,其他线程执行完我还是会执行的。

    四、关于c++中chrono函数的使用

      这个库是c++11定义出来的关于处理时间的库,有了它处理时间问题就会非常方便了。我们在这里简单介绍一下这个库的一些常用方法。

      1、duration_cast(这个主要实现的功能就是可以将单位进行转换,比如说我们获取到的系统时间可能是毫秒,但是我们要把他换算成秒怎么办,就用这个)。

      2、system_clock::now(这个函数的主要目的就是获取到当前系统时间,注意这个时间是当前时间与1970年1月1之间的差值,单位是time_point)

      3、time_since_porch (这个函数也是当前时间与1970年1月1日之间的差值,单位是duration)

      4、localtime(间隔)(这个函数可以将当前时间与1970年的差值,转换成包含今天年月日的结构体,不过注意,传进去的一定是秒)

           5、strftime函数(这个函数可以将结构体指针转换成包含时间格式的字符串数组)

      6、to_time_t(将timepoint时间转换成time_t)

    五、时间函数

      首先我们说一下,时间到底有啥用,其实我想了想,其用途无非就是两点,第一获取到当前的年月日时分秒,第二就是计算两段代码相隔的时间。所以我就着重说这两部分。

      1、获取到当前时间的年月日

        无论是什么函数,他的流程一定是这样的。获取到time_point值,然后获取到tm的值,最后获取到年月日时分秒。

        1、先说第一种方法   

             auto now = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();  //获取到time_point的值并将其转换成秒
          ts = localtime(&now) //获取到当前的tm值
        
             int year = ts.tm_year + 1900;
             int month = ts.tm_mon + 1;
             int day = ts.tm_mday;
              int hour = ts.tm_hour;
             int minute = ts.tm_min;
             int second = ts.tm_sec;
         获取到当前年月日时分秒的值

        2、再说第二种方法
             auto tn = std::chrono::system_clock::now();   // 获取到time_point
             time_t now1 = std::chrono::system_clock::to_time_t(tn);  // 获取time_t的值
             ts = localtime(&now);   // 获取tm的值
             const char *fmt = "%Y-%m-%d %H:%M:%S";
             strftime(buf, sizeof(buf), fmt, ts);   // 将其转换成字符串的形式


       2、获取到当前程序运行的时间
        
          
    auto t0 = std::chrono::system_clock::now();
        j++;
        auto time2 = std::chrono::system_clock::now();
        std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>
                       (std::chrono::system_clock::now() - t0).count()<<std::endl;

      通过得到时间戳相减得到最终的值,另外我测的话一行代码时间58ns,所以只好设置na秒级别了。

      这就是通过sleep_for函数引发的思考。






          










      

      

  • 相关阅读:
    QT 开发小记
    linux c 时间函数
    ubuntu 16.04 登录后黑屏
    ubuntu 16.04 修正网卡与ifname对应关系
    HTML5 Shiv完美解决IE(IE6/IE7/IE8)不兼容HTML5标签的方法
    vue里面引入jq的方法
    如何禁用手机自带的输入法软键盘
    vue的首页渲染了两次的原因以及解决方法
    vue使用hightchats
    解决微信小程序使用switchTab跳转后页面不刷新的问题
  • 原文地址:https://www.cnblogs.com/songyuchen/p/14038180.html
Copyright © 2011-2022 走看看