聊聊C++线程同步机制

  线程同步是一个经常出现的场景,考虑一个生产者消费者模式,一个线程作为生产,一个线程作为消费。生产者往一个队列中加入元素,消费者往一个队列中取元素。实现对一个公共区域的同时访问操作,是C++多线程经常会遇到的问题,所以C++提供了线程同步的机制。

  1.消费者轮询。

参考下面代码:一个线程运行Producer,一个线程运行Comsumer,共同操作一个队列,这会导致严重问题:CPU会被跑满、一个线程加任务,一个线程取任务,导致共享资源被同时访问。当任务较少时,消费者循环访问队列,CPU被无效使用。这种方式好比你无时无刻都要去检查你钱包里的钱有没有多出来,有的话就用了它,这样你估计会累死。

std::queue<Element> que;

void Producer()
{
    while (true)                 //循环放数据
    {
        que.push(Element());
    }
}
void Comsumer()
{
    while (true)         //有数据,取数据
    {
        if (!que.empty())
            que.pop();
    }
}
int main()
{
    std::thread thProducer(Producer);
    std::thread thComsumer(Comsumer);
    //......省略以下代码
    return 0;
}

解决CPU被无效使用的情况,我们可以用线程短暂休眠。则就是第二种方式。 

2.消费者轮询加延迟。

将消费者和生产者都加上延迟,这样当没有任务时,消费者休眠,生产者投放,节约了CPU。这种情况就是,你每隔2小时检查你的钱包里的钱,有就花了,没有就再休息。在任务量小时,出现问题的概率少,在任务量大时,会严重出现共享资源同时访问的问题----生产者消费者同时操作公共队列。

不恰当的例子就是:两个人分别往钱包里放钱和取钱,OK,结果把钱包撤破了,扯破了之后谁都用不了了。所有我们希望消费者和生成者任一时刻,只有一个人在访问公共的队列。

void Comsumer()
{
    while (true)         //有数据,取数据
    {
        if (!que.empty())
            que.pop();
        if (que.empty())
            std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

引出我们的第三种方式,互斥量 。

3.使用std::mutex。锁的特点是:当获取锁操作失

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值