1. 程式人生 > 實用技巧 >C++11 實現訊號量(吃水果問題)

C++11 實現訊號量(吃水果問題)

轉載自https://www.cnblogs.com/zhangbaochong/p/5879263.html

c++11中有互斥和條件變數但是並沒有訊號量,但是利用互斥和條件變數很容易就能實現訊號量。

1.訊號量

  訊號量是一個整數 count,提供兩個原子(atom,不可分割)操作:P 操作和 V 操作,或是說 wait 和 signal 操作。

  • P操作 (wait操作):count 減1;如果 count < 0 那麼掛起執行執行緒;
  • V操作 (signal操作):count 加1;如果 count <= 0 那麼喚醒一個執行執行緒;

2.訊號量的實現

  吃水果問題:桌子有一隻盤子,只允許放一個水果,父親專向盤子放蘋果,母親專向盤子放桔子兒子專等吃盤子的桔子,女兒專等吃盤子的蘋果。只要盤子為空,父親或母親就可以向盤子放水果,僅當盤子有自己需要的水果時,兒子和女兒可從盤子取出。請給出四個人之間的同步關係,並用pv操作實現四個人的正確活動的問題。

  

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

using namespace std;

class semaphore
{
public:
    //初始化訊號個數
    semaphore(int value = 1) :count(value) {}

    void P()//相當於訊號P操作,申請一個訊號
    {
        unique_lock<mutex> lck(mtk);
        
if (--count < 0)//資源不足掛起執行緒 cv.wait(lck); } void V()//相當於V操作,釋放一個訊號 { unique_lock<mutex> lck(mtk); if (++count <= 0)//有執行緒掛起,喚醒一個 cv.notify_one(); } private: int count; mutex mtk; condition_variable cv; }; //有蘋果、橙子、盤子三種訊號 semaphore plate(1
), apple(0), orange(0); void father() { while (true) { //可用盤子減一 plate.P(); cout << "往盤中放一個蘋果" << endl; //蘋果加一 apple.V(); } } void mother() { while (true) { //盤子減一 plate.P(); cout << "往盤中放一個橘子" << endl; //橙子加一 orange.V(); } } void son() { while (true) { //蘋果減一 apple.P(); cout << "兒子吃蘋果" << endl; //盤子加一 plate.V(); } } void daughter() { while (true) { //橙子減一 orange.P(); cout << "女兒吃橘子" << endl; //盤子加一 plate.V(); } } int main() { thread f(father), m(mother), s(son), d(daughter); f.join(); m.join(); s.join(); d.join(); system("pause"); return 0; }