ホームページ  >  記事  >  バックエンド開発  >  ミューテックスを使用して同時実行ゴルーチンで相互排他を確保するにはどうすればよいですか?

ミューテックスを使用して同時実行ゴルーチンで相互排他を確保するにはどうすればよいですか?

Patricia Arquette
Patricia Arquetteオリジナル
2024-10-30 16:38:26550ブラウズ

How to Ensure Mutual Exclusion in Concurrent Goroutines Using Mutexes?

同時実行ゴルーチンでの相互排除: コード分離の実現

同時プログラミングでは、複数のゴルーチンの実行を防ぐメカニズムを導入することが重要です。同じコードを同時に実行します。これにより、データの整合性が確保され、予期しない動作が防止されます。

次のシナリオを考えてみましょう:

<code class="go">Routine 1 {
do something

*Send int to Routine 2
Send int to Routine 3
Print Something
Print Something*

do something
}

Routine 2 {
do something

*Send int to Routine 1
Send int to Routine 3
Print Something
Print Something*

do something
}

Routine 3 {
do something

*Send int to Routine 1
Send int to Routine 2
Print Something
Print Something*

do something
}</code>

ここでは、do something マーカー間のコード セクションが実行されている間、制御が次の 2 つのマーカーに流れるのを防ぎたいと考えています。他のゴルーチン。たとえば、Routine1 がスター内の部分を実行している場合、Routine2 と Routine3 をブロックする必要があります。

WaitGroup による相互排除の実現

相互排除を強制する 1 つのアプローチは、次のとおりです。 sync.WaitGroup を使用します。ただし、ゴルーチンを選択的にブロックする機能がないため、この手法はこのシナリオには適用できません。

分離のためのミューテックスの利用

より効果的な解決策は、同期を使用することです。 .ミューテックス。ミューテックスは、常に 1 つの goroutine だけがそれを所有できることを保証します。ミューテックスを使用して相互排他を実装する方法は次のとおりです:

<code class="go">package main

import (
    "fmt"
    "sync"
)

var (
    mutex1, mutex2, mutex3 sync.Mutex
)

func Routine1() {
    mutex1.Lock()
    // do something
    for i := 0; i < 200; i++ {
        mutex2.Lock()
        mutex3.Lock()
        fmt.Println("value of z")
        mutex2.Unlock()
        mutex3.Unlock()
    }
    // do something
    mutex1.Unlock()
}

func Routine2() {
    mutex2.Lock()
    // do something
    for i := 0; i < 200; i++ {
        mutex1.Lock()
        mutex3.Lock()
        fmt.Println("value of z")
        mutex1.Unlock()
        mutex3.Unlock()
    }
    // do something
    mutex2.Unlock()
}

func Routine3() {
    mutex3.Lock()
    // do something
    for i := 0; i < 200; i++ {
        mutex1.Lock()
        mutex2.Lock()
        fmt.Println("value of z")
        mutex1.Unlock()
        mutex2.Unlock()
    }
    // do something
    mutex3.Unlock()
}

func main() {
    go Routine1()
    go Routine2()
    Routine3()
}</code>

このコードでは:

  • 各ゴルーチンのミューテックス (mutex1、mutex2、mutex3) を定義します。
  • 各ゴルーチン (Routine1、Routine2、Routine3) では、最初にミューテックスをロックし、最後にロックを解除して、内部のクリティカル セクションを保護します。
  • ゴルーチンがすでにロックされているミューテックスをロックしようとしたとき別のゴルーチンによってロックされている場合、ミューテックスが使用可能になるまでブロックされます。

その結果、各ゴルーチン内の print ステートメントは一度に 1 つずつ実行され、それが完了するまで他のゴルーチンがそれらの行にアクセスできないようになります。現在のゴルーチンはロックを解放しました。

以上がミューテックスを使用して同時実行ゴルーチンで相互排他を確保するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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