20230122日志
2023年1月22日
golang #
sync.cond #
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()
}
}()
cpu空转
type Donation struct {
balance int
ch chan int
}
donation := &Donation{ch: make(chan int)}
// Listener goroutines
f := func(goal int) {
for balance := range donation.ch {
if balance >= goal {
fmt.Printf("$%d goal reached\n", balance)
return
}
}
}
go f(10)
go f(15)
// Updater goroutine
for {
time.Sleep(time.Second)
donation.balance++
donation.ch <- donation.balance
}
只能有一个goroutine能接收到10,print出来可能大于10
type Donation struct {
cond *sync.Cond
balance int
}
donation := &Donation{
cond: sync.NewCond(&sync.Mutex{}),
}
// Listener goroutines
f := func(goal int) {
donation.cond.L.Lock()
for donation.balance < goal {
donation.cond.Wait()
}
fmt.Printf("%d$ goal reached\n", donation.balance)
donation.cond.L.Unlock()
}
go f(10)
go f(15)
// Updater goroutine
for {
time.Sleep(time.Second)
donation.cond.L.Lock()
donation.balance++
donation.cond.L.Unlock()
donation.cond.Broadcast()
}
通过con让每个goroutine有机会接受检查
wait的机制
- unlock
- 暂停goroutine, wait notify
- notify arrive, lock
cond的缺点,向chan结构发送通知时,即使没有活动的接收方,消息也会被缓冲,保证了通知将在事件中被接收。 broadcast时,如果没有等待者,将会错过通知