Go 言語のロックとミューテックスのメカニズムに精通している

WBOY
リリース: 2024-03-27 08:33:03
オリジナル
1014 人が閲覧しました

熟悉 Go 语言中的锁和互斥机制

Go 言語は、特に同時プログラミングにおいて非常に人気のあるプログラミング言語です。また、並行プログラミングを扱う場合、ロックと相互排他メカニズムは避けられません。この記事ではGo言語におけるロックと相互排除の仕組みを紹介します。

1. ミューテックス ロック

ミューテックス ロックは最も基本的なロック メカニズムであり、Go 言語でも広く使用されています。場合によっては、複数の goroutine が同時にシェア変数にアクセスすることがありますが、この場合は、mutex ロックを使用して、1 つの goroutine のみがシェア変数に同時にアクセスできないように制限する必要があります。

Go 言語では、ミューテックス ロックの使用は非常に簡単で、コード セグメントの前後に mutex.Lock()mutex.Unlock を追加するだけです。 ()、mutex は sync.Mutex 型の変数です。

次のサンプル コードでは、共有変数に同時にアクセスする複数の goroutine をシミュレートしましたが、このとき、mutex ロックにより、同時に 1 つの goroutine だけが変数値を変更できるようになります。

package main

import (
    "fmt"
    "sync"
)

var count int
var mutex sync.Mutex

func main() {
    for i := 0; i < 10; i++ {
        go increment()
    }
    fmt.Scanln()
}

func increment() {
    for i := 0; i < 10000; i++ {
        mutex.Lock()
        count++
        mutex.Unlock()
    }
}
ログイン後にコピー

2. 読み取り/書き込みロック

上記の例では、ミューテックス ロックを使用して共有変数へのアクセスを制限します。ただし、読み取り操作の方が書き込み操作よりも頻繁に行われる場合があり、この場合、ミューテックス ロックを使用すると、他の goroutine の読み取りおよび書き込み操作がブロックされるため、読み取りパフォーマンスの低下につながります。

この問題を解決するために、Go 言語は読み取り/書き込みロックと呼ばれる特別なロック メカニズムを提供します。読み取り/書き込みロックは、同時に複数の読み取り操作のゴルーチンをサポートできますが、書き込み操作の進行中は、すべての読み取り操作と書き込み操作を除外する必要があります。

Go 言語では、読み取り/書き込みロックの使用も非常に簡単です。読み取り操作に対して保護する必要があるコード セグメントの前後に rwlock.RLock()rwlock.RUnlock() を追加するだけで済みます。また、rwlock.Lock も追加する必要があります。 ( ) および rwlock.Unlock() は書き込み操作に使用されます。このうち、rwlock は sync.RWMutex 型の変数です。

次の例は、複数のゴルーチンが同時に共有変数を読み取る状況を示しています。効率的な読み取り操作を確保するために読み取り/書き込みロックを使用します。

package main

import (
    "fmt"
    "sync"
)

var count int
var rwlock sync.RWMutex

func main() {
    for i := 0; i < 10; i++ {
        go read()
    }
    fmt.Scanln()
}

func read() {
    for i := 0; i < 10000; i++ {
        rwlock.RLock()
        fmt.Println(count)
        rwlock.RUnlock()
    }
}
ログイン後にコピー

3. アトミック操作

場合によっては、単純な加算および減算操作を実行するだけで済み、これはアトミック操作によって実現できます。アトミック操作により、複数のゴルーチンでのこれらの単純な操作の実行順序が安定し、競合状態が回避されます。

Go 言語では、sync/atomic パッケージ内のいくつかの関数を通じてアトミック操作を実装できます。たとえば、 atomic.AddInt32(&count, 1) この関数は、アトミック加算によって count 変数に 1 を加算できます。

次の例は、アトミック操作を使用して、複数のゴルーチンの変数の値を安全にインクリメントする方法を示しています。

package main

import (
    "fmt"
    "sync/atomic"
)

var count int32

func main() {
    for i := 0; i < 10; i++ {
        go increment()
    }
    fmt.Scanln()
}

func increment() {
    for i := 0; i < 10000; i++ {
        atomic.AddInt32(&count, 1)
    }
}
ログイン後にコピー

要約すると、Go 言語は共有変数へのアクセスを保護するためにさまざまなロックと相互排他メカニズムを提供し、競合状態を回避するためにアトミック操作もサポートします。 Go 言語開発者にとって、これらのメカニズムの使用に慣れることは非常に重要です。

以上がGo 言語のロックとミューテックスのメカニズムに精通しているの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!