ホームページ > バックエンド開発 > Golang > 「range」を使用した Go マップの同時反復は安全ですか?また、それはどのように達成できますか?

「range」を使用した Go マップの同時反復は安全ですか?また、それはどのように達成できますか?

Susan Sarandon
リリース: 2024-12-13 17:43:21
オリジナル
609 人が閲覧しました

Is Concurrent Iteration Over Go Maps with `range` Safe, and How Can It Be Achieved?

Go での Range を使用したマップへの同時アクセス

Go での range キーワードを使用したマップへの同時アクセスの概念は、よく誤解されます。この問題を明確にするために、マップに同時にアクセスすることの複雑さと、range を使用することの影響を調べてみましょう。

Range 式の評価

for ステートメント内の range 式は、ループの前に 1 回だけ評価されます。特定のシナリオを除き、開始します。マップの場合、範囲式は単にマップ変数を指します。

Range を使用した反復

range を使用した反復中に、キー変数と値変数 (ほとんどの場合 k と v)各反復中にマップの値を保持します。ただし、反復の実行中に for ブロック内ではマップ アクセスは発生しません。これは、k 値と v 値が次の反復に設定されるときに発生します。

安全な同時反復

これらの概念を理解すると、ロックを使用してマップ上で安全に同時反復を実行できます。反復中のマップ。ただし、反復内のロック解除は、早期のリターンを処理する遅延ステートメントとして実行する必要があります。

var testMap = make(map[int]int)
var testMapLock = &sync.RWMutex{}

func IterateMapKeys(iteratorChannel chan int) error {
    testMapLock.RLock()
    defer testMapLock.RUnlock()
    for k, v := range testMap {
        testMapLock.RUnlock()
        someFunc()
        testMapLock.RLock()
        if someCond {
            return someErr
        }
    }
    return nil
}
ログイン後にコピー

同時変更

このタイプのロック スキームは同時アクセスに対してのみ保護されることに注意することが重要です。 。他のゴルーチンによる同時変更を妨げません。ただし、変更が書き込みロックで保護されている場合、変更は安全なままですが、for ループは必ずしも新しいペアに対して反復されるとは限りません。

安全でない実践

for ブロック内の読み取りロックのロックを解除する他のゴルーチンがマップを変更し、競合状態を引き起こす可能性があるため、安全ではありません。

以上が「range」を使用した Go マップの同時反復は安全ですか?また、それはどのように達成できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート