いろいろ備忘録日記

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

Goメモ-496 (mutex.TryLock)(ロック取得をノンブロッキングに)

関連記事

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

概要

以下、自分用のメモです。

sync.Mutex に、Go 1.18 から TryLock が追加されました。

通常、LockUnlock で事足りるのですが、場合によってはロック取得をノンブロッキングにしたいときがあります。

そういうときに TryLock を使うと便利です。

サンプル

mutex_trylock.go

package syncs

import (
    "sync"
    "time"

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

// MutexTryLock は、Go 1.18 で追加された mutex.TryLock() についてのサンプルです。
//
// > TryLock tries to lock m and reports whether it succeeded.
//
// > (TryLockはmをロックしようとし、成功したかどうかを報告します。)
//
// mutex.TryLock() は、ロック取得をノンブロッキングにしたい場合に利用できます。
//
// # REFERENCES
//
//   - https://pkg.go.dev/sync@go1.22.1#Mutex.TryLock
func MutexTryLock() error {
    const (
        WAIT_SECS = 5
    )

    var (
        m         sync.Mutex
        start     = make(chan struct{})
        lock5secs = func() {
            m.Lock()
            defer m.Unlock()

            close(start)
            time.Sleep(WAIT_SECS * time.Second)
        }
        printStatus = func() {
            output.Stdoutf("[TryLock]", "%s\tTryLock=%v\n", time.Now().Format(time.TimeOnly), m.TryLock())
        }
    )

    // 5秒間 mutex をロックし続ける
    go lock5secs()
    <-start

    for range WAIT_SECS {
        printStatus()
        time.Sleep(1 * time.Second)
    }

    // ここは mutex がアンロックされているのでロックが取れる
    printStatus()
    defer m.Unlock()

    return nil
}

実行

$ task
task: [build] go build -o "/workspace/try-golang/try-golang" .
task: [run] ./try-golang -onetime

ENTER EXAMPLE NAME: syncs_mutex_trylock

[Name] "syncs_mutex_trylock"
[TryLock]            04:28:53   TryLock=false
[TryLock]            04:28:54   TryLock=false
[TryLock]            04:28:55   TryLock=false
[TryLock]            04:28:56   TryLock=false
[TryLock]            04:28:57   TryLock=false
[TryLock]            04:28:58   TryLock=true


[Elapsed] 5.001394093s

参考情報

github.com

Goのおすすめ書籍


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

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