こんにちは。Tomoyuki(@tomoyuki65)です。
Go言語(Golang)のバージョン1.25から「sync.WaitGroup」に新しいメソッド「Go」が追加され、新しいgoroutineの書き方ができるようになりました。
この記事では、そんなGo言語(Golang)のsync.WaitGroup.Goの使い方についてご紹介します。
Go言語(Golang)sync.WaitGroup.Goの使い方|Go1.25の新機能によるgoroutineの新しい書き方
sync.WaitGroupとは?
Go言語で並行処理を扱う際によく使われるのがsync.WaitGroupで、これは複数のgoroutineの処理がすべて完了するまで待機するための仕組みです。
基本的には以下のような流れで使用し、複数の非同期処理を安全に同期させることができます。
2. メソッド「Done」を使ってgoroutine内で処理完了時にカウントを減らす
3. メソッド「Wait」を使って全ての処理が終わるまで待つ
sync.WaitGroupのメソッド「Go」とは?
Goのバージョン1.25でsync.WaitGroupに新しく追加されたメソッドが「Go」です。
このメソッドによってgoroutineの起動と完了管理を簡潔に書くことが可能になり、コードがシンプルになるだけでなく、Done()の書き忘れといったミスも防ぎやすくなります。
特にgoroutineを多用するコードについては、可読性と安全性の両方を向上させることができるので、その点がメリットになります。
従来の書き方(Go1.24以前)
goroutineの書き方について、従来の書き方(Go1.24以前)は以下の通りです。
package main
import (
"fmt"
"sync"
"time"
)
func main() {
// sync.WaitGroupの定義
var wg sync.WaitGroup
for i := 1; i <= 3; i++ {
// メソッド「Add」でgoroutineの数をカウント
wg.Add(1)
go func(n int) {
// メソッド「Done」で処理完了時にカウントを減らす
defer wg.Done()
fmt.Printf("開始: タスク %d\n", n)
time.Sleep(time.Duration(n) * time.Second)
fmt.Printf("終了: タスク %d\n", n)
}(i)
}
fmt.Println("すべてのタスクの完了を待っています...")
// メソッド「Wait」で全ての処理が終わるのを待つ
wg.Wait()
fmt.Println("すべて完了!")
}
実行結果
すべてのタスクの完了を待っています...
開始: タスク 3
開始: タスク 2
開始: タスク 1
終了: タスク 1
終了: タスク 2
終了: タスク 3
すべて完了!
新しい書き方(Go1.25以上)
goroutineの新しい書き方(Go1.25以上)は以下の通りです。
package main
import (
"fmt"
"sync"
"time"
)
func main() {
// sync.WaitGroupの定義
var wg sync.WaitGroup
for i := 1; i <= 3; i++ {
// 【重要】メソッド「Go」に引数を渡せないのでコピーが必要
i := i
// メソッド「Go」で簡潔に記述
wg.Go(func() {
fmt.Printf("開始: タスク %d\n", i)
time.Sleep(time.Duration(i) * time.Second)
fmt.Printf("終了: タスク %d\n", i)
})
}
fmt.Println("すべてのタスクの完了を待っています...")
// メソッド「Wait」で全ての処理が終わるのを待つ
wg.Wait()
fmt.Println("すべて完了!")
}
実行結果
すべてのタスクの完了を待っています...
開始: タスク 3
開始: タスク 1
開始: タスク 2
終了: タスク 1
終了: タスク 2
終了: タスク 3
すべて完了!
最後に
今回はGo言語(Golang)のsync.WaitGroup.Goの使い方についてご紹介しました。
引数を渡したい場合は注意が必要ですが、メソッド「Go」を使った新しい書き方の方が可読性と安全性の両方を向上させることができます。
Goのバージョン1.25以上を利用する際は、ぜひ参考にしてみて下さい。



コメント