go 多协程怎么同步

题目来源: 北京合链

答案:

通过sync同步

通过 sync.WaitGroup 实现,WaitGroup对象内部有一个计数器,最初从0开始, WaitGroup 有三个方法
Add(): 计数器增加N
Done(): 完成一个任务,计数器减少1
Wait(): 同步阻塞,计数器为0之后才继续向下执行

  1. var wg sync.WaitGroup
  2. // 完成1-10对公共切片进行赋值并将其值进行平方
  3. var wg sync.WaitGroup
  4. data := make([]int, 10)
  5. for i := 0; i < 10; i++ {
  6. wg.Add(1)
  7. go func(idx int, w *sync.WaitGroup) {
  8. data[idx] = idx
  9. w.Done()
  10. }(i, &wg)
  11. }
  12. wg.Wait()
  13. fmt.Println(data)
  14. for j := 0; j < 10; j++ {
  15. wg.Add(1)
  16. go func(idx int, w *sync.WaitGroup) {
  17. data[idx] = int(math.Pow(float64(data[idx]), 2))
  18. w.Done()
  19. }(j, &wg)
  20. }
  21. wg.Wait()
  22. fmt.Println(data)

通过channel同步
例子同上sync例子

  1. ch := make(chan bool, 10)
  2. data := make([]int, 10)
  3. for i := 0; i < 10; i++ {
  4. go func(idx int) {
  5. defer func() {
  6. if err := recover(); err != nil {
  7. ch <- false
  8. }
  9. }()
  10. data[idx] = idx
  11. ch <- true
  12. }(i)
  13. }
  14. fmt.Println(data)
  15. for i := 0; i < 10; i++ {
  16. go func(idx int) {
  17. defer func() {
  18. if err := recover(); err != nil {
  19. ch <- false
  20. }
  21. }()
  22. data[idx] = int(math.Pow(float64(data[idx]), 2))
  23. ch <- true
  24. }(i)
  25. }
  26. for j := 0; j < 10; j++ {
  27. fmt.Print(<-ch, " ")
  28. }

参考资料

https://itopic.org/goroutine.html