ホームページ >バックエンド開発 >Golang >golang はどこをロックする必要がありますか?

golang はどこをロックする必要がありますか?

PHPz
PHPzオリジナル
2023-04-25 15:10:44881ブラウズ

Golang プログラミングでは、ロックは同時実行性を制御するための重要なメカニズムです。ただし、すべての場合にロックが必要なわけではなく、場合によっては、ロックによりコードが複雑になり、パフォーマンスに影響を与えることがあります。

それでは、Golang プログラミングではどのような状況でロックが必要になるのでしょうか?

  1. 複数のゴルーチンが共有変数にアクセスする

複数のゴルーチンが同じ変数に同時に書き込む場合、ロックする必要があります。これは、golang の同期はチャネルとロック メカニズムを通じて実現されるためです。ロックがロックされていない場合、競合状態が発生し、データの不整合が発生する可能性があります。

例:

var count int
func addCount(value int) {
   count += value
}

この例では、複数のゴルーチンが同時に addCount 関数を呼び出すと、count の値は次のようになります。正しくない。

この問題を解決するには、sync.Mutex 型を使用してロックします。たとえば、次のようになります。

var count int
var mu sync.Mutex
func addCount(value int) {
   mu.Lock()
   defer mu.Unlock()
   count += value
}

この例では、mu を使用します。 Lock() count をロックして、各ゴルーチンが動作時に変数を排他的に占有できるようにします。

  1. 複数のゴルーチンが読み取りおよび書き込み操作を実行する

複数のゴルーチンが読み取りおよび書き込み操作を実行する場合、ロックも必要です。これは、golang では読み取りと書き込みはどちらもアトミックな操作ですが、読み取りと書き込みの操作が重複してデータの不整合が発生する可能性があるためです。

例:

var m map[int]string
func writeToMap(key int, value string) {
   m[key] = value
}
func readFromMap(key int) string {
   return m[key]
}

この例では、複数のゴルーチンが map に対して読み取りおよび書き込み操作を同時に実行すると、競合状態が発生し、その結果、不整合のデータ。

この問題を解決するには、sync.RWMutex 型を使用してロックします。たとえば、次のようになります。

var m map[int]string
var mu sync.RWMutex
func writeToMap(key int, value string) {
   mu.Lock()
   defer mu.Unlock()
   m[key] = value
}
func readFromMap(key int) string {
   mu.RLock()
   defer mu.RUnlock()
   return m[key]
}

この例では、mu を使用します。 RLock() mu.RUnlock() は、それぞれ読み取りと書き込みをロックおよびロック解除します。

  1. 複数の goroutine 間の同期

複数の goroutine 間で同期が必要な場合は、ロックも必要です。 golang ではゴルーチン間を同期するためにチャネルがよく使用されますが、チャネルが適用できない場合は、ロック メカニズムを使用する必要があります。

例:

var wg sync.WaitGroup
var mu sync.Mutex
var data []int
func worker() {
   defer wg.Done()
   for i := 0; i < 1000; i++ {
      mu.Lock()
      data = append(data, i)
      mu.Unlock()
   }
}
func main() {
   for i := 0; i < 10; i++ {
      wg.Add(1)
      go worker()
   }
   wg.Wait()
   fmt.Println(data)

この例では、10 個のゴルーチンが 1000 個の整数を同時に data に追加します。 data は共有変数であるため、sync.Mutex を使用してロックする必要があります。

まとめると、golang プログラミングでロックを使用する必要がある状況には、複数のゴルーチンが共有変数にアクセスする状況、複数のゴルーチンが読み取りおよび書き込み操作を実行する状況、および複数のゴルーチン間で同期が必要な状況が含まれます。ロックを使用する場合は、プログラムの正確性とパフォーマンスを確保するために、実際の状況に応じて適切なロック タイプを選択する必要があります。

以上がgolang はどこをロックする必要がありますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。