Please enable Javascript to view the contents

Golang交替打印的几种实现方式

 ·  ☕ 2 分钟  ·  ✍️ 卓 · 👀... 阅读

提供了Golang交替打印的几个思路: 使用Goroutine, sync包中的WaitGroup和Cond

  1. 使用unbuffered channel实现

    •  1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      
      func PrintABUnbufferedChannel() {
          // 使用2个channel实现交替运行
          c1 := make(chan struct{})
          c2 := make(chan struct{})
      
          // 打印aaa的函数, 对2个channel执行send操作
          PrintA := func() {
              for {
                  c1 <- struct{}{}
                  fmt.Println("aaa")
                  time.Sleep(1 * time.Second)
                  c2 <- struct{}{}
              }
          }
      
          // 打印bbb的函数, 对2个channel执行receive操作
          PrintB := func() {
              for {
                  <-c2
                  fmt.Println("bbb")
                  time.Sleep(1 * time.Second)
                  <-c1
              }
          }
      
          // 先打印aaa
          go func() {
              <-c1
          }()
      
          go PrintA()
          go PrintB()
      
          time.Sleep(1 * time.Hour)
      
      }
      
  2. 使用sync.Cond配合sync.WaitGroup实现

    •  1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      
      func PrintABCond() {
          // 使用2个cond实现交替运行
          c1 := sync.NewCond(&sync.Mutex{})
          c2 := sync.NewCond(&sync.Mutex{})
      
          // 使用waitgroup协调顺序, 确保printA, printB先启动, 再发送第一个signal
          var wg sync.WaitGroup
      
          // 打印aaa的函数, 等待c1, 通知c2
          printA := func() {
              // 确保printA启动早于第一个signal
              wg.Done()
              for {
                  c1.L.Lock()
                  // 等待信号
                  c1.Wait()
                  fmt.Println("aaa")
                  time.Sleep(1 * time.Second)
                  // 发送信号
                  c2.Signal()
                  c1.L.Unlock()
              }
          }
      
          // 打印bbb的函数, 等待c2, 通知c1
          printB := func() {
              // 确保printB启动早于第一个signal
              wg.Done()
              for {
                  c2.L.Lock()
                  // 等待信号
                  c2.Wait()
                  fmt.Println("bbb")
                  time.Sleep(1 * time.Second)
                  // 发送信号
                  c1.Signal()
                  c2.L.Unlock()
              }
          }
      
          wg.Add(2)
      
          // 先打印aaa
          go func() {
              // 等待printA, printB启动后, 再发送第一个signal
              wg.Wait()
              c1.Signal()
          }()
      
          go printA()
          go printB()
      
          time.Sleep(1 * time.Hour)
      }
      
  3. 使用for-select语句实现, 与方法1类似

    •  1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      
      func PrintABForSelect() {
      
          c1 := make(chan struct{})
          c2 := make(chan struct{})
      
          printAB := func() {
              for {
                  select {
                  case <-c1:
                      fmt.Println("aaa")
                      time.Sleep(1 * time.Second)
                      c2 <- struct{}{}
                  case <-c2:
                      fmt.Println("bbb")
                      time.Sleep(1 * time.Second)
                      c1 <- struct{}{}
                  }
              }
          }
      
          go func() {
              c1 <- struct{}{}
          }()
      
          go printAB()
          go printAB()
      
          time.Sleep(1 * time.Hour)
      }
      
分享

目录