关于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函数引发的思考。






      










  

  

原文地址:https://www.cnblogs.com/songyuchen/p/14038180.html