channels_basics.go 935 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. )
  6. func main() {
  7. odd := make(chan struct{}) // 奇数 goroutine 的令牌
  8. even := make(chan struct{}) // 偶数 goroutine 的令牌
  9. done := make(chan struct{}) // 用来通知主函数结束
  10. var wg sync.WaitGroup
  11. wg.Add(2)
  12. // 打印奇数:1,3,5,7,9
  13. go func() {
  14. defer wg.Done()
  15. for i := 1; i <= 10; i += 2 {
  16. <-odd // 等令牌
  17. fmt.Println(i)
  18. if i == 9 { // 最后一个奇数,不再发令牌
  19. close(done)
  20. return
  21. }
  22. even <- struct{}{} // 把令牌给偶数 goroutine
  23. }
  24. }()
  25. // 打印偶数:2,4,6,8,10
  26. go func() {
  27. defer wg.Done()
  28. for i := 2; i <= 10; i += 2 {
  29. <-even // 等令牌
  30. fmt.Println(i)
  31. if i == 10 { // 打印完 10,直接退出
  32. return
  33. }
  34. odd <- struct{}{} // 把令牌还给奇数 goroutine
  35. }
  36. }()
  37. // 主 goroutine 先把令牌给 odd,启动交替流程
  38. odd <- struct{}{}
  39. // 等结束信号
  40. <-done
  41. wg.Wait()
  42. }