如何开启
func say(name string) {
fmt.Println("hello, I'm",name)
time.Sleep(time.Second)
}
func main() {
//如何开启线程
go say("rui")
say("z")
}
如何让主线程等待goroutines
var wg sync.WaitGroup
func say(name string) {
fmt.Println("hello, I'm",name)
time.Sleep(time.Second*5)
wg.Done()
}
func main() {
wg.Add(2)//等待2个任务完成
go say("rui")
go say("z")
wg.Wait()//等待其他goroutines完成
fmt.Println("exit")
}
模拟打球
var wg sync.WaitGroup
func play(name string ,ch chan int) {
defer wg.Done()//写在前面
for true {
ball,ok:=<-ch
if !ok{//通道关闭
fmt.Printf("%s win!\n",name)
return//结束方法
}
source := rand.NewSource(time.Now().UnixNano())
r := rand.New(source)
n := r.Intn(100)
if n%10==0 {//把球打飞
close(ch)
fmt.Printf("%s lose the ball\n",name)
return
}
ball++
fmt.Printf("%s receive the ball %dtimes \n",name,ball)
ch<-ball
}
}
func main() {
ch := make(chan int, 0)
wg.Add(2)//等待2个任务完成
go play("one",ch)
go play("two",ch)
ch<-0//线程启动后才能启用channel,不然没有人接收
wg.Wait()//等待其他goroutines完成
fmt.Println("exit")
}
Race Condition的三种解决方案
var counter int32
var wait sync.WaitGroup
func UnsafeIntCounter() {
defer wait.Done()
for i := 0; i < 10000; i++ {
counter++
}
}
func main() {
wait.Add(2)
go UnsafeIntCounter()
go UnsafeIntCounter()
wait.Wait()
fmt.Println(counter)
}
//10237
- sync.Mutex ```go //全局 var mtx sync.Mutex
//函数中 mtx.Lock() counter++ mtx.Unlock()
2. atomic
```go
func AtomicIntCounter() {
defer wait.Done()
for i := 0; i < 10000; i++ {
atomic.AddInt32(&counter,1)
}
}
3.