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()
}
發佈了103 篇原創文章 · 獲贊 42 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章