两个协程交替打印一个数组,使数组中的数据按顺序输出

参考解析

题目来源:小米

答案:

使用两个channel,一个专门用于通信的 channel,另一个用于输出消息,使用两个协程进行打印数组,一个协程进行数组的访问,也能将此协程改为 main 函数的主协程。下面这种写法在打印完数组后不会退出!

  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. )
  6. var wg sync.WaitGroup
  7. func worker1(ch chan struct{}, data chan interface{}) {
  8. defer wg.Done()
  9. for {
  10. select {
  11. case <-ch:
  12. tmp := <-data
  13. //更清楚看见输出!
  14. time.Sleep(time.Second * 1)
  15. fmt.Printf("%v ", tmp)
  16. ch <- struct{}{} //发送信号
  17. default:
  18. }
  19. }
  20. }
  21. func worker2(ch chan struct{}, data chan interface{}) {
  22. defer wg.Done()
  23. ch <- struct{}{} // 先发送信号
  24. for {
  25. select {
  26. case <-ch:
  27. tmp := <-data
  28. time.Sleep(time.Second * 1)
  29. fmt.Printf("%v ", tmp)
  30. ch <- struct{}{} //发送信号
  31. default:
  32. }
  33. }
  34. }
  35. func main() {
  36. done := make(chan struct{})
  37. data := make(chan interface{})
  38. wg.Add(1)
  39. go func() {
  40. defer wg.Done()
  41. /*s1 := []int{1, 2, 3, 4, 5, 6}*/
  42. s1 := []string{"a", "b", "c", "d", "e", "f"}
  43. for _, v := range s1 {
  44. data <- v
  45. }
  46. }()
  47. wg.Add(2)
  48. go worker1(done, data)
  49. go worker2(done, data)
  50. wg.Wait()
  51. }