C++ 信号量的实现和使用

转载:c++11用互斥和条件变量实现信号量 - zhangbaochong - 博客园 (cnblogs.com)

问题:

 吃水果问题:桌子有一只盘子,只允许放一个水果,父亲专向盘子放苹果,母亲专向盘子放桔子 儿子专等吃盘子的桔子,女儿专等吃盘子的苹果。只要盘子为空,父亲或母亲就可以向盘子放水果, 仅当盘子有自己需要的水果时,儿子和女儿可从盘子取出。请给出四个人之间的同步关系,并用 pv操作实现四个人的正确活动的问题。

重点:

1.主要的思路就是一个人在执行的时候,其他人全部在等待,等这个人执行完了,就唤醒其他人。

#include <ctime>
#include <atomic>
using namespace std;

class semaphore
{
public:
    semaphore(int value = 1) :count(value) {}

    void wait()
    {
        unique_lock<mutex> lck(mtk);
        if (--count < 0)//资源不足挂起线程
        {
            cout << count << endl;
            cv.wait(lck);
        }
          
    }

    void signal()
    {
        unique_lock<mutex> lck(mtk);
        if (++count <= 0)//有线程挂起,唤醒一个
        {
            cout << count << endl;
            cv.notify_one();
        }       
    }

private:
    int count;
    mutex mtk;
    condition_variable cv;
};

semaphore plate(1), apple(0), orange(0);
void father()
{
    while (true)
    {
        plate.wait();
        cout << "往盘中放一个苹果" << endl;
        apple.signal();
    }
}

void mother()
{
    while (true)
    {
        plate.wait();
        cout << "往盘中放一个橘子" << endl;
        orange.signal();
    }
}

void son()
{
    while (true)
    {
        apple.wait();
        cout << "儿子吃苹果" << endl;
        plate.signal();
    }
}

void daughter()
{
    while (true)
    {
        orange.wait();
        cout << "女儿吃橘子" << endl;
        plate.signal();
    }
}

int main()
{
    thread f(father), m(mother), s(son), d(daughter);
    f.join();
    m.join();
    s.join();
    d.join();
    return 0;
}

总结:

前面看错了,以为所有人共享count,其实每个人一个count,其中plate共享一个count,一开始,四个线程同时进入wait,但是女儿和儿子线程被锁住,因为他们的count减1后小于0,而母亲和父亲共用的count一开始是1,所以要么父亲先执行,要么母亲先执行,然后另一个被锁住因为count=-1。假设父亲先执行,母亲则被锁住,然后父亲唤醒儿子的线程,然后父亲继续wait,这个时候父亲的count是-2,但是儿子执行plate.signle,则要么唤醒父亲要么唤醒母亲,因为父亲母亲同时被锁住,假如母亲被唤醒,则母亲执行女儿的signle,然后循环下去。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值