正确理解Go语言中的sync.Cond

本文详细介绍了Go语言中的sync.Cond同步原语,通过一个捐赠目标应用的示例,展示了如何使用sync.Cond解决繁忙循环问题,以及它与channel、sync.Mutex的关系和使用注意事项。
摘要由CSDN通过智能技术生成

        在sync包的同步原语中,sync.Cond可能是最少被使用和理解的。但是,它提供了我们无法通过channel实现的功能。下面我们通过一个具体的示例来展示sync.Cond何时有用以及如何使用它。

下面的示例实现了捐赠目标机制:每当达到特定目标时都会发出警报的应用程序。我们将有一个goroutine负责增加余额(一个更新器 goroutine )。其他 goroutine 将接收更新并在达到特定目标时打印一条消息(一些监听器 goroutine)。例如,一个 goroutine 正在等待10美元的捐赠目标,而另一个 goroutine 正在等待15美元的捐赠目标。

首先尝试的实现是使用互斥锁。更新器 goroutine 每秒增加余额,而那些监听器 goroutine 开始循环直到达到它们的捐赠目标:

type Donation struct {
    mu             sync.RWMutex
    balance int
}
donation := &Donation{}
 
/ Listener goroutines
f := func(goal int) {
    donation.mu.RLock()
    for donation.balance < goal {
        donation.mu.RUnlock()
        donation.mu.RLock()
    }
    fmt.Printf("$%d goal reached\n", donation.balance)
    donation.mu.RUnlock()
}
go f(10)
go f(15)
 
/ Updater goroutine
go func() {
    for {
        time.Sleep(time.Second)
        donation.mu.Lock()
        donation.balance++
        donation.mu.Unlock()
    }
}()

我们使用互斥锁保护对共享变量donation.balance的访问。如果我们运行这个例子,它会按预期工作:

$10 goal reached
$15 goal reached

主要问题--以及使这个实现变得糟糕的原因--是繁忙的循环。每个监听器 goroutine 一直循环,直到达到其捐赠目标,这会浪费大量CPU 周期并使CPU 使用量巨大。我们需要找到更好的解决方案。

   

  • 15
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mindfulness code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值