经典问题:go多线程编程

713 阅读1分钟
  1. 使用两个goroutine交替打印1-100之间的奇数和偶数, 输出时按照从小到大输出.

无缓冲的chan可以实现同步等待。

func Test_Multi(t *testing.T) {
   var wg sync.WaitGroup
   ch := make(chan struct{})
   wg.Add(2)
   go func() {
      defer wg.Done()
      for i := 0; i < 10; i++ {
         if i%2 == 0 {
            fmt.Println(i)
         }
         ch <- struct{}{}
      }
   }()

   go func() {
      defer wg.Done()
      for i := 0; i < 10; i++ {
         if i%2 == 1 {
            fmt.Println(i)
         }
         <-ch
      }
   }()
   wg.Wait()
}


func Test_Multi(t *testing.T) {
   var wg sync.WaitGroup
   ch := make(chan struct{})
   wg.Add(2)
   go func() {
      defer wg.Done()
      for i := 0; i < 10; i += 2 {
         fmt.Println(i)
         ch <- struct{}{}
         <-ch

      }
   }()

   go func() {
      defer wg.Done()
      for i := 1; i < 10; i += 2 {
         <-ch
         fmt.Println(i)
         ch <- struct{}{}
      }
   }()
   wg.Wait()

}
  1. N个 协程 交替打印1-100

  • 启动N个协程,共用一个外部变量计数器,计数器范围是1到100
  • 开启N个有缓冲chan,chans[i]塞入数据代表协程i可以进行打印了,打印的数字就是计数器的数
  • 协程i一直阻塞,直到chan[i]通道有数据可以拉,才打印

package main

import "fmt"

func main() {
   print(5)
}


func print(num int) {
   var chanSlice []chan int
   for i:=0; i<num; i++ {
      chanSlice = append(chanSlice, make(chan int, 1))
   }
   quitChan := make(chan struct{})

   res := 1
   next := 0
   for i:=0; i<num; i++ {
      go func(i int) {
         for {
            <- chanSlice[i]
            if res>100 {
               quitChan <- struct{}{}
               return
            }
            fmt.Println(i, res)
            res++

            if next == num-1 {
               next = 0
            } else {
               next++
            }
            chanSlice[next] <- 1
         }

      }(i)
   }
   chanSlice[0] <- 1
   select {
   case <- quitChan:
      fmt.Println("exit")
   }

}