C++ boost thread學習(二)

來源:互聯網
上載者:User

標籤:blog   對象   ack   通知   oid   capacity   技術分享   comm   ace   

 條件變數 

如果線程之間執行順序上有依賴關係,可使用條件變數(Condition variables)。 

可以到boost官網中參考條件變數(Condition variables)的使用。 

條件變數必須和互斥量配合使用,等待另一個線程重某個事件的發生(滿足某個條件),然後線程才能繼續執行。

共有兩種條件變數對象condition_variable, condition_variable_any,一般情況下使用condition_variable_any。 

條件變數的使用方式: 
擁有條件變數的線程先鎖定互斥量,然後迴圈檢查某個條件,如果條件不滿足,那麼就調用條件變數的成員函數wait()等待直到條件滿足。其他線程處理條件變數要求的條件,當條件滿足時調用它的成員函數notify_one()或者notify_all(),以通知一個或者所有正在等待條件的變數的線程停止等待繼續執行。 

例子:生產--消費模型。 

緩衝區buffer使用了兩個條件變數cond_put和cond_get,分別用於處理put動作和get動作,如果緩衝區滿則cond_put持續等待,當cond_put得到通知 (緩衝區不滿)時線程寫入資料,然後通知cond_get條件變數可以擷取資料。cond_get的處理流程與cond_put類似。 

C++代碼  
  1. #include <boost/thread.hpp>  
  2. #include <boost/thread/mutex.hpp>  
  3.   
  4. #include <iostream>  
  5. #include <stack>  
  6.   
  7. using namespace std;  
  8.   
  9. boost::mutex io_mu;  
  10.   
  11. class buffer  
  12. {  
  13. private:  
  14.     boost::mutex mu; // 互斥量,配合條件變數使用  
  15.     boost::condition_variable_any cond_put; // 寫入條件變數  
  16.     boost::condition_variable_any cond_get; // 讀取條件變數  
  17.   
  18.     stack<int> stk; // 緩衝區對象  
  19.     int un_read, capacity;  
  20.     bool is_full() // 緩衝區滿判斷  
  21.     {  
  22.         return un_read == capacity;  
  23.     }  
  24.     bool is_empty()  // 緩衝區空判斷  
  25.     {  
  26.         return un_read == 0;  
  27.     }  
  28.   
  29. public:  
  30.     buffer(size_t n) : un_read(0), capacity(n){}  // 建構函式  
  31.     void put(int x)  // 寫入資料  
  32.     {  
  33.         { // 開始一個局部域  
  34.             boost::mutex::scoped_lock lock(mu); //鎖定互斥量  
  35.             while ( is_full() ) // 檢查緩衝區是否滿  
  36.             {  
  37.                 { // 局部域,鎖定cout輸出一條資訊  
  38.                     boost::mutex::scoped_lock lock(io_mu);  
  39.                     cout << "full waiting..." << endl;  
  40.                 }  
  41.                 cond_put.wait(mu); // 條件變數等待  
  42.             } // 條件變臉滿足,停止等待  
  43.             stk.push(x); // 壓棧,寫入資料  
  44.             ++un_read;  
  45.         } // 解鎖互斥量,條件變數的通知不需要互斥量鎖定  
  46.         cond_get.notify_one(); // 通知可以讀取資料  
  47.     }  
  48.   
  49.     void get(int *x) // 讀取資料  
  50.     {  
  51.         { // 局部域開始  
  52.             boost::mutex::scoped_lock lock(mu); // 鎖定互斥量  
  53.             while (is_empty()) // 檢查緩衝區是否空  
  54.             {  
  55.                 {  
  56.                     boost::mutex::scoped_lock lock(io_mu);  
  57.                     cout << "empty waiting..." << endl;  
  58.                 }  
  59.                 cond_get.wait(mu); // 條件變數等待  
  60.             }  
  61.             --un_read;  
  62.             *x = stk.top(); // 讀取資料  
  63.             stk.pop(); // 彈棧  
  64.         }  
  65.         cond_put.notify_one(); // 通知可以寫入資料  
  66.     }  
  67. };  
  68.   
  69. buffer buf(5); // 一個緩衝區對象  
  70. void producter(int n) // 生產者  
  71. {  
  72.     for (int i = 0; i < n; ++i)  
  73.     {  
  74.         {  
  75.             boost::mutex::scoped_lock lock(io_mu);  
  76.             cout << "put " << i << endl;  
  77.         }  
  78.         buf.put(i); // 寫入資料  
  79.     }  
  80. }  
  81.   
  82. void consumer(int n) // 消費者  
  83. {  
  84.     int x;  
  85.     for (int i = 0; i < n; ++i)  
  86.     {  
  87.         buf.get(&x); // 讀取資料  
  88.         boost::mutex::scoped_lock lock(io_mu);  
  89.         cout << "get " << x << endl;  
  90.     }  
  91. }  
  92.   
  93. int main()  
  94. {  
  95.     boost::thread t1(producter, 20); // 一個生產者線程  
  96.     boost::thread t2(consumer, 10); // 兩個消費者線程  
  97.     boost::thread t3(consumer, 10);  
  98.   
  99.     t1.join();  
  100.     t2.join();  
  101.     t3.join();  
  102.   
  103.     return 0;  
  104. }  


運行結果: 
empty waiting... 
put 0 
empty waiting... 
put 1 
put 2 
get 1 
get 2 
get 0 
empty waiting... 
empty waiting... 
put 3 
put 4 
put 5 
put 6 
put 7 
get 6 
get 7 
get 5 
get 4 
get 3 
empty waiting... 
put 8 
empty waiting... 
put 9 
put 10 
put 11 
get 9 
get 11 
get 8 
empty waiting... 
put 12 
put 13 
put 14 
put 15 
put 16 
put 17 
full waiting... 
get 10 
get 16 
put 18 
full waiting... 
get 17 
get 15 
get 14 
get 13 
get 12 
get 18 
empty waiting... 
put 19 
get 19 

C++ boost thread學習(二)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.