いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-589 (Go 1.25でsync.WaitGroupにGoメソッドが追加)(Go 1.25 rc1)

関連記事

GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ

概要

以下、自分用のメモです。前回の続きです。

devlights.hatenablog.com

Go 1.25 のドラフトリリースノートは以下。

tip.golang.org

上記を見ると、Go 1.25 で sync.WaitGroup に Go メソッドが追加されるみたいですね。

$ go version
go version go1.25rc1 linux/amd64

$ go doc sync.waitgroup.go
package sync // import "sync"

func (wg *WaitGroup) Go(f func())
    Go calls f in a new goroutine and adds that task to the WaitGroup. When f
    returns, the task is removed from the WaitGroup.

    The function f must not panic.

    If the WaitGroup is empty, Go must happen before a WaitGroup.Wait.
    Typically, this simply means Go is called to start tasks before Wait is
    called. If the WaitGroup is not empty, Go may happen at any time. This means
    a goroutine started by Go may itself call Go. If a WaitGroup is reused to
    wait for several independent sets of tasks, new Go calls must happen after
    all previous Wait calls have returned.

    In the terminology of the Go memory model, the return from f "synchronizes
    before" the return of any Wait call that it unblocks.

[the Go memory model]: https://go.dev/ref/mem

WaitGroupを使う場合に大抵記載する以下の処理

wg.Add(1)
go func() {
    defer wg.Done()
    処理
}()

を便利関数として用意してくれた感じ。少し記載が楽になるのと見やすくなりますね。

試してみた

package main

import (
        "log"
        "math/rand"
        "sync"
        "time"
)

func main() {
        log.SetFlags(log.Lmicroseconds)

        if err := run(); err != nil {
                panic(err)
        }
}

func run() error {
        const (
                COUNT = 10
        )
        var (
                wg sync.WaitGroup
        )
        for i := range COUNT {
                wg.Go(func() {
                        delay := time.Duration(rand.Float64()*1000) * time.Millisecond
                        time.Sleep(delay)
                        log.Printf("[%02d] hello world (%v)\n", i+1, delay)
                })
        }

        wg.Wait()

        return nil
}

実行すると以下のようになります。

$ go run .
19:05:07.684969 [10] hello world (300ms)
19:05:07.689136 [08] hello world (304ms)
19:05:07.715336 [07] hello world (330ms)
19:05:07.830717 [01] hello world (445ms)
19:05:07.954246 [06] hello world (569ms)
19:05:08.003209 [05] hello world (618ms)
19:05:08.024737 [09] hello world (639ms)
19:05:08.087019 [04] hello world (702ms)
19:05:08.313381 [02] hello world (928ms)
19:05:08.375850 [03] hello world (990ms)

参考情報

Goのおすすめ書籍


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。