golang ゴルーチンとチャネルの使い方と注意点
今回はgolangのゴルーチンとチャネルについて解説していきます。
ゴルーチンとチャネル
Go言語でのゴルーチンとチャネルは、並行プログラミングを行う際使用するツールです。
ゴルーチンは軽量スレッドのようなもので、非常に低いオーバーヘッドで多数の処理を同時に実行できます。
チャネルはゴルーチン間でデータを安全にやり取りするためのメカニズムです。
ゴルーチンとチャネルの使い方
ゴルーチンの起動
ゴルーチンの起動は非常に簡単で、goを関数呼び出しの前に置くことで、その関数は新しいゴルーチンで非同期に実行されます。
go func() {
fmt.Println("Hello from a goroutine!")
}()
チャネルの作成と使用
make関数を使用してチャネルを作成し、ゴルーチン間でデータを送受信します。
ch := make(chan int)
go func() {
ch <- 42 // チャネルに値を送信
}()
value := <-ch // チャネルから値を受信
fmt.Println(value)
チャネルを通じた同期
チャネルは受信操作が行われるまで送信側をブロックする特性を持っています。これを利用して、ゴルーチンの完了を待つことができます。
done := make(chan bool)
go func() {
fmt.Println("Working...")
time.Sleep(1 * time.Second) // 何かの処理
done <- true // 処理完了を通知
}()
<-done // 完了を待つ
fmt.Println("Done!")
ゴルーチンとチャネルの注意点
デッドロック
ゴルーチンがチャネルの読み書きを待っているが、その操作を完了できる他のゴルーチンが存在しない場合、デッドロックが発生します。
デッドロックを避けるためには、チャネルの操作が常にペアで完了するよう設計する必要があります。
リソースの枯渇
無制限にゴルーチンを生成すると、システムのリソースを枯渇させる可能性があります。
ゴルーチンの数は必要最小限に抑え、必要に応じてゴルーチンプールを使用することを検討する必要があります。
チャネルのクローズ
チャネルをクローズすることで、それ以上の値が送信されないことを受信側に通知できます。しかし、すでにクローズされたチャネルに対して値を送信しようとすると、パニックが発生します。
チャネルをクローズする前に、すべての送信が完了していることを確認する必要があります。
非ブロッキング操作
select文を使用して複数のチャネル操作を非ブロッキングで扱うことができます。
defaultケースを使用するとどのチャネルも即座に利用可能でない場合に他の処理を実行できます。
select {
case msg := <-ch:
fmt.Println("Received:", msg)
default:
fmt.Println("No message received")
}
golangをもっと詳しくなりたい方に
初めてのGo言語
Go言語の入門から応用まではこの一冊で網羅されています。説明も順序立てて説明されており完成度の高い参考書となっています。
詳解Go言語Webアプリケーション開発
こちらはGo言語の基礎知識を得たあとに読むことをすすめる本となっています。ハンズオン形式で手を動かしながら実装をしていくことができるため、実際の開発を意識しながらGo言語を学ぶことができます。
以下の記事では他にも筆者が実際に読んでおすすめしたい本をまとめています。
【Go入門】Golang基礎入門 + 各種ライブラリ + 簡単なTodoWebアプリケーション開発(Go言語)
まだGo言語の勉強を始めていない方、全くの初心者の方にはこちらのUdemy教材が最もおすすめです。
この教材ではgolangの基礎について網羅的に学ぶことができます。ただ見て学ぶだけでなく、講座の中でアプリ作成まで行うことで学んだことの理解をさらに深めることができます。
現役シリコンバレーエンジニアが教えるGo入門 + 応用でビットコインのシストレFintechアプリの開発
個人的に最も勉強になったのは「現役シリコンバレーエンジニアが教えるGo入門 + 応用でビットコインのシストレFintechアプリの開発」という教材です。
本格的なレクチャーに入る前に、なぜGoなのか、なぜFintechなのかについて説明されていることで、Goの概念や意味について大枠から理解することができます。
以下の記事では筆者が実際に受講したおすすめUdemy教材をまとめています。
この記事が気に入ったらサポートをしてみませんか?