如何开启

  1. func say(name string) {
  2. fmt.Println("hello, I'm",name)
  3. time.Sleep(time.Second)
  4. }
  5. func main() {
  6. //如何开启线程
  7. go say("rui")
  8. say("z")
  9. }

如何让主线程等待goroutines

  1. var wg sync.WaitGroup
  2. func say(name string) {
  3. fmt.Println("hello, I'm",name)
  4. time.Sleep(time.Second*5)
  5. wg.Done()
  6. }
  7. func main() {
  8. wg.Add(2)//等待2个任务完成
  9. go say("rui")
  10. go say("z")
  11. wg.Wait()//等待其他goroutines完成
  12. fmt.Println("exit")
  13. }

模拟打球

  1. var wg sync.WaitGroup
  2. func play(name string ,ch chan int) {
  3. defer wg.Done()//写在前面
  4. for true {
  5. ball,ok:=<-ch
  6. if !ok{//通道关闭
  7. fmt.Printf("%s win!\n",name)
  8. return//结束方法
  9. }
  10. source := rand.NewSource(time.Now().UnixNano())
  11. r := rand.New(source)
  12. n := r.Intn(100)
  13. if n%10==0 {//把球打飞
  14. close(ch)
  15. fmt.Printf("%s lose the ball\n",name)
  16. return
  17. }
  18. ball++
  19. fmt.Printf("%s receive the ball %dtimes \n",name,ball)
  20. ch<-ball
  21. }
  22. }
  23. func main() {
  24. ch := make(chan int, 0)
  25. wg.Add(2)//等待2个任务完成
  26. go play("one",ch)
  27. go play("two",ch)
  28. ch<-0//线程启动后才能启用channel,不然没有人接收
  29. wg.Wait()//等待其他goroutines完成
  30. fmt.Println("exit")
  31. }

Race Condition的三种解决方案

  1. var counter int32
  2. var wait sync.WaitGroup
  3. func UnsafeIntCounter() {
  4. defer wait.Done()
  5. for i := 0; i < 10000; i++ {
  6. counter++
  7. }
  8. }
  9. func main() {
  10. wait.Add(2)
  11. go UnsafeIntCounter()
  12. go UnsafeIntCounter()
  13. wait.Wait()
  14. fmt.Println(counter)
  15. }
  16. //10237
  1. sync.Mutex ```go //全局 var mtx sync.Mutex

//函数中 mtx.Lock() counter++ mtx.Unlock()

  1. 2. atomic
  2. ```go
  3. func AtomicIntCounter() {
  4. defer wait.Done()
  5. for i := 0; i < 10000; i++ {
  6. atomic.AddInt32(&counter,1)
  7. }
  8. }

3.