golangで複数のスレッドから同じ変数を共有する方法は何ですか

Go言語では、goroutineとchannelを利用して並行処理における変数の共有を実現できます。

  1. Goルーチンとチャネルを使用する:
  2. goroutineを使用して複数のスレッドを作成し、それぞれが並行して実行できます。
  3. スレッド間の通信とデータ共有にはチャネルを使用し、スレッドセーフを確保する。
  4. チャネルを介して指定されたgoroutineにデータを送信し、チャネルから別のgoroutineからのデータを受信します。
  5. 次のコード例を参照してください。
  6. package mainimport (
    “fmt”
    “sync”
    )

    var wg sync.WaitGroup

    func worker(id int, jobs <-chan int, results chan<- int) {
    for j := range jobs {
    fmt.Println(“Worker”, id, “started job”, j)
    results <- j * 2 // 結果をresultsチャネルに送信
    }
    wg.Done()
    }

    func main() {
    jobs := make(chan int, 100)
    results := make(chan int, 100)

    // 3つのワーカーゴルーチンを作成
    for w := 1; w <= 3; w++ {
    wg.Add(1)
    go worker(w, jobs, results)
    }

    // jobsチャネルにタスクを送信
    for j := 1; j <= 9; j++ {
    jobs <- j
    }
    close(jobs)

    // resultsチャネルから処理結果を受信
    for a := 1; a <= 9; a++ {
    <-results
    }

    // ワーカーゴルーチンの終了を待つ
    wg.Wait()
    }

  7. 上記の例では、goroutineを使用して3つのワーカーを作成し、それらがjobsチャネルからタスクを受け取り、結果をresultsチャネルに送信します。メイン関数では、jobsチャネルに9つのタスクを送信し、resultsチャネルから9つの結果を受け取ります。
  8. syncパッケージのMutexを使用する:
  9. 共有変数のアクセスを同一時刻に1スレッドのみ許可するには、sync パッケージの Mutex 型を使用して共有変数を保護します。
  10. 共有変数にアクセスする前にLockメソッドを使用して共有変数をロックし、アクセスした後にUnlockメソッドを使用してアンロックします。
  11. 例として次のコードがあります。
  12. package mainimport (
    “fmt”
    “sync”
    )

    var (
    counter int
    wg sync.WaitGroup
    mutex sync.Mutex
    )

    func worker() {
    defer wg.Done()
    for i := 0; i < 1000; i++ {
    mutex.Lock()
    counter++
    mutex.Unlock()
    }
    }

    func main() {
    wg.Add(2)
    go worker()
    go worker()
    wg.Wait()
    fmt.Println(“カウンタ:”, counter)
    }

  13. 共有変数counterを保護するためにsyncのMutex型を利用し、同期的に1つのスレッドのみがcounterにアクセスできるようにします。各ワーカー関数では、counterを使用する前にLockメソッドを利用してロックし、使用後はUnlockメソッドでロックを解除し、最後にcounterの値を出力します。

Goルーチンとチャネルを用いるか、排他制御を用いるかは、どちらでマルチスレッドの変数共有を実現しても構いません。具体的にどちらを用いるのかは、業務の場面と要求によって異なります。

bannerAds