1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Go言語(Golang)における、goroutineとchannelの使い方の基本的な例

Posted at
package main

import (
	"fmt"
	"sync"
)

func main() {
	ch1 := make(chan int)
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		defer wg.Done()
		fmt.Println(<-ch1)
	}()
	ch1 <- 10
	close(ch1)

	v, ok := <-ch1
	fmt.Printf("%v %v\n", v, ok)
	wg.Wait()

	ch2 := make(chan int, 2)
	ch2 <- 1
	ch2 <- 2
	close(ch2)

	v, ok = <-ch2
	fmt.Printf("%v %v\n", v, ok)

	v, ok = <-ch2
	fmt.Printf("%v %v\n", v, ok)

	v, ok = <-ch2
	fmt.Printf("%v %v\n", v, ok)
}

このコードは、goroutineを使って非同期にデータを受信し、channelを使ってデータの送受信を行う基本的な例です。

gooroutineは、Go言語の並行処理を実現するための仕組みです。goキーワードを使って新しいgoroutineを作成します。goroutineは軽量なスレッドとして動作し、独立して実行されます。

channelは、goroutine間でデータを安全にやり取りするための構造です。Goでは、channelを使って値を送受信することができます。

	ch1 := make(chan int)
  • channelの作成: 整数型のchannel ch1を作成します。このchannelは、goroutine間で整数を送受信するために使用されます。
	var wg sync.WaitGroup
  • WaitGroupの宣言: sync.WaitGroup型の変数wgを宣言します。これにより、複数のgoroutineが終了するのを待つことができます。
	wg.Add(1)
  • カウントの追加: wgに1を追加します。これにより、現在1つのgoroutineが終了するのを待つことを示します。
	go func() {
  • goroutineの開始: 無名関数を新しいgoroutineとして実行します。この関数内のコードは、メインのgoroutineとは別に並行して実行されます。
		defer wg.Done()
  • defer文: この行は、関数の終了時にwg.Done()を呼び出すことを指定します。これにより、wgのカウントが1減ります。goroutineが終了したことを示します。
		fmt.Println(<-ch1)
  • channelからの受信: ch1から値を受信し、その値をコンソールに出力します。<-ch1は、ch1から値を読み取る操作です。この操作は、ch1に値が送信されるまでブロックされます。
	}()
  • 無名関数の終了: ここで無名関数の定義が終了し、goroutineが実行を開始します。
	ch1 <- 10
  • channelへの送信: メインのgoroutineからch1に整数10を送信します。この操作により、先ほどのgoroutineがfmt.Printlnで受信した値として10が出力されます。
	close(ch1)
  • channelの閉鎖: ch1を閉じます。これにより、これ以上の値を送信しないことを示します。受信側は、channelが閉じられたことを知ることができます。
	v, ok := <-ch1
  • channelからの再受信: ch1から値を受信しようとしますが、ch1は既に閉じられているため、okfalseになります。vには0が設定されます(整数型のデフォルト値)。
	fmt.Printf("%v %v\n", v, ok)
  • 出力: 受信した値vと、受信が成功したかどうかを示すokの値をフォーマットしてコンソールに出力します。
	wg.Wait()
  • WaitGroupの待機: wgのカウントが0になるまでメインのgoroutineをブロックします。ここでは、先ほどのgoroutineが終了するのを待ちます。
	ch2 := make(chan int, 2)
  • バッファ付きchannelの作成: 整数型のバッファ付きchannel ch2を作成します。このchannelは最大2つの値を保持できます。
	ch2 <- 1
  • channelへの送信: ch2に整数1を送信します。この操作は非ブロッキングです。バッファが空いているため、すぐに送信が完了します。
	ch2 <- 2
  • channelへの送信: ch2に整数2を送信します。この操作も非ブロッキングで、バッファが空いているため、すぐに完了します。
	close(ch2)
  • channelの閉鎖: ch2を閉じます。これにより、これ以上の値を送信しないことを示します。
	v, ok = <-ch2
  • channelからの受信: ch2から値を受信します。ここでは、最初に送信された値1が受信され、vに1が、oktrueが設定されます。
	fmt.Printf("%v %v\n", v, ok)
  • 出力: 受信した値vと、受信が成功したかどうかを示すokの値をフォーマットしてコンソールに出力します。
	v, ok = <-ch2
  • channelからの再受信: ch2から次の値を受信します。ここでは、2が受信され、vに2が、oktrueが設定されます。
	fmt.Printf("%v %v\n", v, ok)
  • 出力: 受信した値vと、受信が成功したかどうかを示すokの値をフォーマットしてコンソールに出力します。
	v, ok = <-ch2
  • channelからの再受信: ch2から値を受信しようとしますが、ch2は既に閉じられているため、vには0が、okにはfalseが設定されます。
	fmt.Printf("%v %v\n", v, ok)
  • 出力: 受信した値vと、受信が成功したかどうかを示すokの値をフォーマットしてコンソールに出力します。
1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?