Golang:如何优雅的让所有子协程执行完后再执行主协程

Golang:如何优雅的让所有子协程执行完后再执行主协程

方法一:channel 实现同步

使用 channel 来完成同步功能。

/*
@Time : 2019-10-28 下午 5:30
@Author : Gerald
@File : 用channel来实现同步
@Software: GoLand
*/
package main

import (
	"fmt"
)


func printString(str string) {
	for _, data := range str {
		fmt.Printf("%c", data)
	}
	fmt.Printf("\n")
}

var ch = make(chan int)
var tongBu = make(chan int)

func person1() {
	printString("Gerald")
	tongBu <- 1
	ch <- 1
}

func person2() {
	<- tongBu
	printString("Seligman")
	ch <- 2
}


func main() {
	// 目的:使用 channel 来实现 person1 先于 person2 执行
	go person1()

	go person2()

	count := 2

	// 判断所有协程是否退出
	for range ch {
		count--

		if 0 == count {
			close(ch)
		}
	}

}
  • count 表示有所少个协程
  • ch 用来子协程与主协程之间的同步
  • tongBu 用来两个协程之间的同步
  • 主协程阻塞等待数据,每当一个子协程执行完后,就会往 ch 里面写一个数据,主协程收到后会使 count–,当 count 减为 0,关闭 ch,主协程将不阻塞在 range ch。

方法二:sync.WaitGroup

Go 语言提供一个更简单的方式就是,sync.WaitGroup 来实现等待。

sync.WaitGroup 内部是实现了一个计数器,它有三个方法

  • Add() 用来设置一个计数
  • Done() 用来在操作结束时调用,使计数减1
  • Wait() 用来等待所有的操作结束,即计数变为0。
/*
@Time : 2019-10-28 下午 5:30
@Author : Gerald
@File : 用channel来实现同步
@Software: GoLand
*/
package main

import (
   "fmt"
   "sync"
)


func printString(str string) {
   for _, data := range str {
      fmt.Printf("%c", data)
   }
   fmt.Printf("\n")
}

// 使用 sync.WaitGroup 的方式来实现主协程等待其他子协程
var wg sync.WaitGroup

var tongBu = make(chan int)

func person1() {
   printString("Gerald")
   tongBu <- 1
 
   wg.Done()
}

func person2() {
   <- tongBu
   printString("Seligman")

   wg.Done()
}


func main() {
   wg.Add(2)

   // 目的:使用 channel 来实现 person1 先于 person2 执行
   go person1()

   go person2()
   defer close(tongBu)

   wg.Wait()
}

你可能感兴趣的:(Go,语言学习)