戻る

Go言語におけるGoroutineの探求

ニキータ・ハビャ

ニキータ・ハビャ

6分間の読み物

|

4 month前

Goroutinesは、Go言語における並行プログラミングの基盤となる構成要素であり、複数の論理処理を同時に実行可能にすると同時に、それら間の洗練された通信メカニズムを提供します。

プログラミングにおいて、複数の操作を同時に処理する必要がある場合、通常は並行性並列処理という2つの概念について議論します。それぞれの意味を探ってみましょう。

並行性とは何か?

並列処理とは何か?

並行処理と並列処理の違いとは?

ゴルーチンとは? 🔀

ゴルーチンはどう機能するのか? 📊

ゴルーチンの実行

WaitGroupとは? ⏳

WaitGroup のメソッド ⚙️


defer とは何ですか?

  • defer は Go のキーワードであり、関数の実行を周囲の関数が戻るまで遅延させることを可能にします。
  • これは通常、WaitGroup と組み合わせて使用され、エラーが発生した場合でも goroutine の実行が終了した際に必ず _Done()_ メソッドが呼び出されることを保証します。これにより、WaitGroup のカウンタが正しく減算され、メインプロセスが安全に終了できるようになります。

WaitGroup はどのように動作するのでしょうか?

WaitGroupを作成すると、そのカウンタは0から開始します。

go
wg := sync.WaitGroup{}

goroutineを追加する際には、Add()メソッドを呼び出してカウンタを1増加させます。

go
wg.Add(1)

goroutineの実行が終了すると、Done()メソッドを呼び出してカウンタを1減算します。

go
wg.Done()

メインプロセスはWait()メソッドを呼び出し、カウンタがゼロに達するまでブロックできます。これはすべてのgoroutineの実行が完了したことを示します。

go
wg.Wait()

ゴルーチンとWaitGroupの使用例

go
func main() {
	var wg sync.WaitGroup // 1. ゴルーチン終了待ちに使用するWaitGroupを作成

	wg.Add(1) // 2. 最初のgoroutineに対してWaitGroupカウンタを1増加
	go func() {
		defer wg.Done() // 3. このgoroutineが終了したら、WaitGroupのカウンターを1減算する
		fmt.Println("1番目のgoroutineを実行中")
	}() // 4. これは無名関数なので、すぐに呼び出す必要がある

	wg.Add(1) // 5. 2番目のgoroutine用にWaitGroupのカウンターを1増分する
	go func() {
		defer wg.Done()
		fmt.Println("2番目のgoroutineを実行中")
	}()

	wg.Wait() // 6. すべてのgoroutineの実行が完了するまで待機する
	fmt.Println("すべてのgoroutineが実行を完了しました")
}

コードの説明: 📝

  1. ゴルーチン終了待ちに使用する WaitGroup を作成
  2. 最初の goroutine に対して WaitGroup カウンタを 1 増加
  3. このgoroutineが終了したら、WaitGroupのカウンターを1減算する
  4. これは無名関数なので、すぐに呼び出す必要がある
  5. 2番目のgoroutine用にWaitGroupのカウンターを1増分する
  6. すべてのgoroutineの実行が完了するまで待機する

実行順序: ⏰

出力 X:

1番目のgoroutineを実行中
2番目のgoroutineを実行中
すべてのgoroutineが実行を完了しました

出力 Y:

2番目のgoroutineを実行中
1番目のgoroutineを実行中
すべてのgoroutineが実行を完了しました

まとめ: 🤝