mirror of
https://github.com/teivah/100-go-mistakes.git
synced 2026-06-26 19:37:09 +08:00
sync.Cond Demo without time.Sleep()
This commit is contained in:
parent
55854553b1
commit
f3d7f72157
1 changed files with 53 additions and 0 deletions
|
|
@ -96,3 +96,56 @@ func listing3() {
|
||||||
donation.cond.Broadcast()
|
donation.cond.Broadcast()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func listing4() {
|
||||||
|
type Donation struct {
|
||||||
|
cond *sync.Cond
|
||||||
|
jobDone chan struct{}
|
||||||
|
waitDone chan struct{}
|
||||||
|
balance int
|
||||||
|
}
|
||||||
|
|
||||||
|
donation := &Donation{
|
||||||
|
cond: sync.NewCond(&sync.Mutex{}),
|
||||||
|
jobDone: make(chan struct{}),
|
||||||
|
waitDone: make(chan struct{}),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listener goroutines
|
||||||
|
f := func(goal int) {
|
||||||
|
for donation.balance < goal {
|
||||||
|
donation.cond.Wait()
|
||||||
|
if donation.balance < goal {
|
||||||
|
donation.waitDone <- struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Printf("%d$ goal reached\n", donation.balance)
|
||||||
|
donation.jobDone <- struct{}{}
|
||||||
|
donation.cond.L.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
donation.cond.L.Lock()
|
||||||
|
go f(10)
|
||||||
|
donation.cond.L.Lock()
|
||||||
|
go f(15)
|
||||||
|
|
||||||
|
jobNumber := 2
|
||||||
|
// Updater goroutine
|
||||||
|
for jobNumber != 0 {
|
||||||
|
donation.cond.L.Lock()
|
||||||
|
// after get the lock, means all living jobs have been released the lock and in waiting status.
|
||||||
|
waitNumber := jobNumber
|
||||||
|
donation.balance++
|
||||||
|
donation.cond.L.Unlock()
|
||||||
|
donation.cond.Broadcast()
|
||||||
|
for waitNumber != 0 {
|
||||||
|
// no matter job done or wait done, means a job waked and get the lock.
|
||||||
|
select {
|
||||||
|
case <-donation.jobDone:
|
||||||
|
jobNumber -= 1
|
||||||
|
case <-donation.waitDone:
|
||||||
|
}
|
||||||
|
waitNumber -= 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue