0
0

Go言語(Golang) Goroutine記述例

Last updated at Posted at 2024-09-02
package main

import (
	"fmt"
	"sync"
)

// producer関数は整数チャンネルに整数を送信します。
func producer(ch chan int, i int) {
    // チャンネルにi * 2を送信
	ch <- i * 2
}

// consumer関数はチャンネルから受信した整数を処理し、WaitGroupのDoneメソッドを呼び出してカウントを減らします。
func consumer(ch chan int, wg *sync.WaitGroup) {
    // チャンネルから受信した整数を処理
	for i := range ch {
		fmt.Println("process", i*1000)
		wg.Done()
	}
}

func main() {
	// WaitGroupを初期化
	var wg sync.WaitGroup
    // 整数チャンネルを作成
	ch := make(chan int)

	// 10個のプロデューサーゴルーチンを起動
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go producer(ch, i)
	}

    // コンシューマーゴルーチンを起動
	go consumer(ch, &wg)
    // すべてのプロデューサーが終了するまで待機
	wg.Wait()
    // チャンネルを閉じる
	close(ch)
}

プログラムの流れ

  1. WaitGroupの初期化

    var wg sync.WaitGroup
    

    sync.WaitGroupを使って、複数のゴルーチンの終了を待つためのカウンタを作成します。

  2. チャンネルの作成

    ch := make(chan int)
    

    整数を送受信するためのチャンネルを作成します。

  3. プロデューサーゴルーチンの起動

    for i := 0; i < 10; i++ {
        wg.Add(1)
        go producer(ch, i)
    }
    

    10個のプロデューサーゴルーチンを起動します。各ゴルーチンはproducer関数を実行し、i * 2の値をチャンネルに送信します。

  4. コンシューマーゴルーチンの起動

    go consumer(ch, &wg)
    

    1つのコンシューマーゴルーチンを起動します。consumer関数はチャンネルから整数を受信し、それを処理します。

  5. プロデューサーの終了待機

    wg.Wait()
    

    すべてのプロデューサーゴルーチンが終了するのを待ちます。

  6. チャンネルのクローズ

    close(ch)
    

    チャンネルを閉じます。これにより、consumer関数のrangeループが終了します。

出力の詳細

各プロデューサーゴルーチンは、以下のようにi * 2の値をチャンネルに送信します:

  • i = 0の場合、送信値は0 * 2 = 0
  • i = 1の場合、送信値は1 * 2 = 2
  • i = 2の場合、送信値は2 * 2 = 4
  • ...
  • i = 9の場合、送信値は9 * 2 = 18

コンシューマーゴルーチンは、これらの値を受信し、i * 1000を計算して表示します。したがって、出力は以下のようになります:

  • 0 * 1000 = 0
  • 2 * 1000 = 2000
  • 4 * 1000 = 4000
  • ...
  • 18 * 1000 = 18000

出力順はゴルーチンの実行順によるため、必ずしも順番通り(0, 2, 4, ... 18)にはなりませんが、出力される値は以下となる。

process 0
process 2000
process 4000
process 6000
process 8000
process 10000
process 12000
process 14000
process 16000
process 18000

注意点

  • プログラムは、プロデューサーがchに値を送信した後すぐにDoneを呼び出しているため、wg.Waitが終了した時点でchにまだ値が残っている可能性があり、close(ch)が早すぎる問題があります。
  • consumer側でwg.Doneを呼び出すべきでなく、プロデューサー側で呼び出すべきです。また、chを閉じるタイミングも見直す必要があります。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0