mirror of
https://github.com/teivah/100-go-mistakes.git
synced 2026-06-22 01:17:11 +08:00
98 lines
1.5 KiB
Go
98 lines
1.5 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
func listing1() {
|
|
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()
|
|
}
|
|
}()
|
|
}
|
|
|
|
func listing2() {
|
|
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
|
|
}
|
|
}
|
|
|
|
func listing3() {
|
|
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()
|
|
}
|
|
}
|