zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    01矩阵扩展
    蒙特卡罗仿真
    某幂相关数学结论
    分式乘法变加减
    ICPC模板排版工具
    windows下mysql使用实录
    随机题目小结
    工作用linux命令汇总
    小数化分数的O(log2n)解法
    博弈总结
  • 原文地址:https://www.cnblogs.com/-citywall123/p/13532200.html
Copyright © 2011-2022 走看看