GolangでWaitGroupを使っている穴

1238 ワード

Sync.WaitGroupはGolang開発者にとってよく知られていないものではなく、マルチコパス間の同期のメカニズムとしてよく使われています.それをうまく使うと、必ず半分の仕事ができますが、誤用すると問題が発生します.WaitGroupの利用についてはネット上で多くの例がありますが、ここでは紹介しません.私がプロジェクトでWaitGroupを使って出会った穴についてお話ししたいと思います.
       プロジェクトではサーバに同期の必要性があるためWaitGroupを直接使用したが,シーンの使用は考慮されず,結果としてプロジェクトがオンラインになった後,ピーク時にクライアントにカートンが頻繁に発生し,多角的に検索した結果,WaitGroupを使用する場合,単独のgoroutineが起動されなければ,プライマリスレッドのブロックを引き起こす可能性が高いことが分かった.次のテストを行いました
func main() {
   fmt.Println("main-1")
   testchan()
   fmt.Println("main-2")   
}

func testchan() {
	fmt.Println("testchan-1")
	go func() {
		var wg *sync.WaitGroup = new(sync.WaitGroup)
		fmt.Println("testchan-2")
		testchan1(wg)
		fmt.Println("testchan-5")
		wg.Wait()
		time.Sleep(time.Duration(5) * time.Second)
		fmt.Println("testchan-6")
	}()
}

func testchan1(wg *sync.WaitGroup) {
	wg.Add(1)
	fmt.Println("testchan-3")
	time.Sleep(time.Duration(5) * time.Second)
	fmt.Println("testchan-4")
	wg.Done()

}

出力:
main-1
testchan-1
main-2
testchan-2
testchan-3
//5秒後
testchan-4
testchan-5
//あと5秒
testchan-6
まとめ:WaitGroupをgoroutine内に使用すると、プライマリスレッドのブロックは発生せず、同期の効果も得られます.