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;
}

 

posted @ 2020-08-19 21:59  知道了呀~  阅读(2396)  评论(0编辑  收藏  举报