關於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函數引發的思考。






      










 

 

 

 

 

 

 

 

 

  

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM