いろいろ備忘録日記

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

Goメモ-352 (sync.OnceValue)(go 1.21から追加)

関連記事

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

概要

以下、自分用のメモです。忘れない内にメモメモ。。。

Go 1.21 から、syncパッケージに OnceValue って関数が追加されていたのですね。知らなかったです。

https://pkg.go.dev/sync@go1.21.4#OnceValue

元々存在していた sync.Once が使いやすくなった感じですね。動きとしては同じで1度だけ実行される関数にしてくれます。

サンプル

package syncs

import (
    "runtime"
    "sync"

    "github.com/devlights/gomy/output"
)

// UseOnceValue は、Go 1.21 で追加された sync.OnceValue() のサンプルです。
//
// # REFERENCES
//   - https://pkg.go.dev/sync@go1.21.4#OnceValue
func UseOnceValue() error {
    //
    // Go 1.21 にて、sync.OnceValue() が追加された
    // 元々存在していた、sync.Once を使いやすくした感じ
    // 値を返却する関数を使える
    //

    var (
        v = 0
        f = sync.OnceValue(func() int {
            v++
            return v
        })
    )
    output.Stdoutl("[before]", v)

    var (
        numCpu = runtime.NumCPU()
        done   = make(chan bool, numCpu)
    )
    for i := 0; i < numCpu; i++ {
        i := i
        go func() {
            result := f()
            output.Stderrf("[done]", "result=%d\tgoroutine-%d\n", result, i)
            done <- true
        }()
    }

    for i := 0; i < numCpu; i++ {
        <-done
    }

    output.Stdoutl("[after]", v)

    return nil

    /*
       $ task
       task: [build] go build .
       task: [run] ./try-golang -onetime

       ENTER EXAMPLE NAME: syncs_use_oncevalue

       [Name] "syncs_use_oncevalue"
       [before]             0
       [done]               result=1   goroutine-5
       [done]               result=1   goroutine-11
       [done]               result=1   goroutine-4
       [done]               result=1   goroutine-3
       [done]               result=1   goroutine-2
       [done]               result=1   goroutine-12
       [done]               result=1   goroutine-14
       [done]               result=1   goroutine-7
       [done]               result=1   goroutine-6
       [done]               result=1   goroutine-8
       [done]               result=1   goroutine-0
       [done]               result=1   goroutine-1
       [done]               result=1   goroutine-9
       [done]               result=1   goroutine-13
       [done]               result=1   goroutine-15
       [done]               result=1   goroutine-10
       [after]              1


       [Elapsed] 640.98µs
   */
}

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

$ task
task: Task "build" is up to date
task: [run] ./try-golang -onetime

ENTER EXAMPLE NAME: syncs_use_oncevalue

[Name] "syncs_use_oncevalue"
[before]             0
[done]               result=1   goroutine-15
[done]               result=1   goroutine-4
[done]               result=1   goroutine-5
[done]               result=1   goroutine-1
[done]               result=1   goroutine-7
[done]               result=1   goroutine-0
[done]               result=1   goroutine-6
[done]               result=1   goroutine-9
[done]               result=1   goroutine-8
[done]               result=1   goroutine-14
[done]               result=1   goroutine-12
[done]               result=1   goroutine-10
[done]               result=1   goroutine-3
[done]               result=1   goroutine-13
[done]               result=1   goroutine-11
[done]               result=1   goroutine-2
[after]              1


[Elapsed] 615.85µs

参考情報

sync: add OnceFunc, OnceValue, OnceValues · Issue #56102 · golang/go · GitHub

New functions to support sync.Once | by Pranoy Kundu | Oct, 2023 | Medium

Goのおすすめ書籍

Go言語による並行処理

Go言語による並行処理

Amazon


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

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