c++11用互斥和条件变量实现信号量
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 }