c++11中有互斥和條件變量但是並沒有信號量,但是利用互斥和條件變量很容易就能實現信號量。
1.信號量
信號量是一個整數 count,提供兩個原子(atom,不可分割)操作:P 操作和 V 操作,或是說 wait 和 signal 操作。
- P操作 (wait操作):count 減1;如果 count < 0 那么掛起執行線程;
- V操作 (signal操作):count 加1;如果 count <= 0 那么喚醒一個執行線程;
2.信號量的實現
1 #include <iostream> 2 #include <thread> 3 #include <mutex> 4 #include <condition_variable> 5 6 using namespace std; 7 8 class semaphore 9 { 10 public: 11 semaphore(int value = 1) :count(value) {} 12 13 void wait() 14 { 15 unique_lock<mutex> lck(mtk); 16 if (--count < 0)//資源不足掛起線程 17 cv.wait(lck); 18 } 19 20 void signal() 21 { 22 unique_lock<mutex> lck(mtk); 23 if (++count <= 0)//有線程掛起,喚醒一個 24 cv.notify_one(); 25 } 26 27 private: 28 int count; 29 mutex mtk; 30 condition_variable cv; 31 };
3.利用信號量解決吃水果問題
吃水果問題:桌子有一只盤子,只允許放一個水果,父親專向盤子放蘋果,母親專向盤子放桔子 兒子專等吃盤子的桔子,女兒專等吃盤子的蘋果。只要盤子為空,父親或母親就可以向盤子放水果, 僅當盤子有自己需要的水果時,兒子和女兒可從盤子取出。請給出四個人之間的同步關系,並用 pv操作實現四個人的正確活動的問題。
1 semaphore plate(1), apple(0), orange(0); 2 void father() 3 { 4 while (true) 5 { 6 plate.wait(); 7 cout << "往盤中放一個蘋果" << endl; 8 apple.signal(); 9 } 10 } 11 12 void mother() 13 { 14 while (true) 15 { 16 plate.wait(); 17 cout << "往盤中放一個橘子" << endl; 18 orange.signal(); 19 } 20 } 21 22 void son() 23 { 24 while (true) 25 { 26 apple.wait(); 27 cout << "兒子吃蘋果" << endl; 28 plate.signal(); 29 } 30 } 31 32 void daughter() 33 { 34 while (true) 35 { 36 orange.wait(); 37 cout << "女兒吃橘子" << endl; 38 plate.signal(); 39 } 40 } 41 42 int main() 43 { 44 thread f(father), m(mother), s(son), d(daughter); 45 f.join(); 46 m.join(); 47 s.join(); 48 d.join(); 49 50 }