Golangで並列処理をまとめるsync.waitGroupとerrorgroup.Groupの使い方




並列処理

Golangではgorutineを使って処理を並列化させます。この並列処理全てが終わるまで処理を待たせる方法にwaitGroupというものがあるのでその使い方を解説します。

waitGroup

wg.Add(1)で処理待ちをする並列処理の数をインクリメントしていきます。gorutineで何か処理をし、deferでwg.Doneを呼ぶとディクリメントします。全てのgorutineがwg.Done()を呼ぶとwg.Wait()以降の処理を実行することができます。

package main

import (
	"log"
	"sync"
)

func main() {
	var wg sync.WaitGroup
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			// なにか処理
		}()
	}
	wg.Wait()
	log.Println("Finish")
}

waitGroupは並列処理を簡単に扱うことができますが、gorutine内のエラーハンドリングを行うにはchannelを使ってエラーは外に通知したりと追加で実装を行わないといけなく、処理も複雑になってしまいます。

そこでerrorgroupパッケージを使うと処理が簡単になります。

errorgroup

errorgroupは書き方が少し変わってしまいますが、並列化された全てのgorutineが終了するのを待つのは変わりません。

全てのgorutineを処理しきって、エラーがある場合はeg.Wait()からエラーがリターンされます。

errorgroupを使うとwaitGroupよりもエラーハンドリングが簡単になるので複雑になりそうだったらerrorgroupを使うのをおすすめします。

package main

import (
	"log"

	"golang.org/x/sync/errgroup"
)

func main() {
	eg := errorgroup.Group{}
	for i := 0; i < 10; i++ {
		eg.Go(func() error {
			// なにか処理
			return something()
		})
	}
	if err := eg.Wait(); err != nil {
		log.Fatal(err)
	}
	log.Println("Finish")
}

おすすめ書籍

Go言語の初心者から上級者までしっかり学べる書籍となっています。

本書籍はサンプルコードが非常に豊富で、HTTP/Websockert通信、CLIツール、Google/Twitter API、MongoDB等を使った様々なアプリケーションの作り方を学べます。

Go言語特有のgorutine、channelに関してもしっかりと説明されているのでこの書籍を一通り写経するとGoの全体像がつかめるかと思います。もちろん自分は全て写経しました。

The following two tabs change content below.

髙妻智一

2013年CyberAgent新卒入社 スマホゲームを作る子会社に所属し、サーバーサイドのエンジニアを担当。2年目の終わりから新規子会社の立ち上げに参加し、サーバーサイドのエンジニアリーダーとしてサービースのリリースから運用までを担当。 2018年仮想通貨のスマホウォレットを提供するGinco Incにブロックチェーンエンジニアとして入社。






よく読まれている関連記事はこちら



コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です