チャネルとは?
チャネル(Channel)は、プログラム内でデータを受け渡すための通信手段やデータ構造の一つです。
異なるプログラム間でデータを受け渡すために使用され、
データ同期や通信を効率的に行うことが可能です。
主には、並行プログラミングや並列処理のコンテキストで使用されます。
つまり、Go言語のプログラムが得意とする並列処理や並行処理を実装する上でマストの知識となります。
チャネルの特徴
チャネルには、いくつか特徴があるので紹介します。
データの受け渡し
チャネルは、データの送信側と受信側の間でデータの受け渡しをする役割を持っています。
データの橋渡しをするものと捉えてください。
データの同期
チャネルはデータの受け渡しを待つための方法としても機能します。
データが送信されるまで受信側はブロックされ、データが受信されると送信側はブロックされます。
これによって、データの同期と調整が可能になります。
バッファリング
バッファつきのチャネルを使用すると、複数のデータを一時的にキューに格納できます。
これによって、非同期処理の速度の違いを吸収することができます。
ブロッキング
チャネル操作はブロッキングすることがあります。
データが送信または受信できる状態でない場合、操作は待機状態に入り、
データが利用可能になるまで処理が進行しません。
チャネルの使い方
今度は、チャネルの基本的な使い方について解説していきます。
チャネルの作成
チャネルはmake関数を使用して作成します。
以下では、整数型のデータを送受信するためのチャネルを作成しています。
ch := make(chan int)
データの送信
チャネルにデータを送信するには、「
<-」
演算子を使用します。
以下では、整数「42」をチャネル(ch)に送信するしています。
ch <- 42
データの受信
チャネルからデータを受信するためには、「<-」演算子をチャネルの左側に記述します。
以下では、「ch」からデータを受信し、それを変数xに格納しています。
x := <-ch
チャネルのクローズ
次は、チャネルをクローズします。
クローズされたチャネルにはデータの送信は出来ませんが、受信は可能です。
以下では、チャネル(ch)をクローズしています。
close(ch)
非同期通信
チャネルを使用すると、ゴルーチン(並行処理単位)間でデータを非同期に送受信できます。
これによって、並行プログラミングを効率良く構築することが可能です。
ゴルーチンがデータを送信し、別のゴルーチンがそれを受信すると、ブロッキングせずにプログラムを進行させることができます。
select文
ゴルーチンが複数のチャネルからデータを受信する場合や、
タイムアウト処理などの複数の非同期操作を監視する場合に「select」文が役に立ちます。
select文は、最初に準備が完了したケースから実行されます。
サンプルコード
最後に、チャネルを使ったサンプルコードを紹介します。
以下では、チャネルでデータを5秒間だけ送受信をしています。
package main
import (
"fmt"
"time"
)
func main() {
// チャネルを作成
ch1 := make(chan string)
ch2 := make(chan string)
// ゴルーチン1: 1秒ごとにメッセージをch1に送信
go func() {
for {
time.Sleep(1 * time.Second)
ch1 <- "メッセージ1"
}
}()
// ゴルーチン2: 2秒ごとにメッセージをch2に送信
go func() {
for {
time.Sleep(2 * time.Second)
ch2 <- "メッセージ2"
}
}()
// メインゴルーチン: 5秒間だけメッセージを受信
timeout := time.After(5 * time.Second)
for {
select {
case msg1 := <-ch1:
fmt.Println("ch1から受信:", msg1)
case msg2 := <-ch2:
fmt.Println("ch2から受信:", msg2)
case <-timeout:
fmt.Println("5秒経過しました。受付を終了します。")
return
}
}
}
// ch1から受信: メッセージ1
// ch2から受信: メッセージ2
// ch1から受信: メッセージ1
// ch1から受信: メッセージ1
// ch2から受信: メッセージ2
// ch1から受信: メッセージ1
// 5秒経過しました。受付を終了します。
ゴルーチンについては、以下の記事で詳しく解説していますので、ご参考までに!
最後に
ここまで読んでいただきありがとうございます。
今回は、Go言語のチャネルについて解説をしました。
「もっとこうしたほうがいい」などのご意見ありましたら、コメントを頂けると幸いです。
コメント