Go言語でマルチスレッド処理をする方法
Go言語でマルチスレッド処理を行うためには、主に「ゴルーチン」と「チャネル」を使用します。
Go言語は、軽量なスレッドであるゴルーチンを利用して、並行処理を簡単に実現できるのが特徴です。
以下に、基本的なゴルーチンとチャネルの使い方について説明します。
ゴルーチンの利用
ゴルーチンは、Go言語で並行処理を行うための基本的な構成要素です。
ゴルーチンは、goキーワードを使って関数を非同期に実行するためのものです。
以下のコードは、ゴルーチンを使って簡単な並行処理を行う例です。
package main import ( "fmt" "time" ) func printNumbers() { for i := 1; i <= 5; i++ { fmt.Println(i) time.Sleep(time.Second) } } func main() { go printNumbers() // ゴルーチンを起動 time.Sleep(6 * time.Second) // メイン関数が終了する前にゴルーチンが完了するのを待つ }
このコードでは、printNumbers関数をゴルーチンとして実行し、5秒間にわたって1から5までの数字を出力します。
time.Sleepは、ゴルーチンが終了するのを待つために使用しています。
メイン関数が早く終了しないようにするためです。
チャネルの利用
チャネルは、ゴルーチン間でデータを安全に送受信するための通信手段です。
チャネルを使うことで、複数のゴルーチンがデータを共有する際の競合状態を避けることができます。
以下は、チャネルを使ってゴルーチン間でデータをやり取りする例です。
package main import ( "fmt" "time" ) func sendData(ch chan<- int) { for i := 1; i <= 5; i++ { ch <- i time.Sleep(time.Second) } close(ch) // チャネルをクローズ } func main() { ch := make(chan int) // チャネルの作成 go sendData(ch) // ゴルーチンを起動 for num := range ch { // チャネルからデータを受信 fmt.Println(num) } }
この例では、sendData関数が整数データをチャネルに送信します。
メイン関数では、そのチャネルからデータを受信し、出力します。
チャネルがクローズされると、rangeループは終了します。
ゴルーチンとチャネルを使ったパターン
より複雑な並行処理の例として、複数のゴルーチンを起動し、それぞれからデータをチャネルを通じて受信するパターンを示します。
package main import ( "fmt" "time" ) func worker(id int, ch chan<- string) { for i := 1; i <= 3; i++ { ch <- fmt.Sprintf("Worker %d: %d", id, i) time.Sleep(time.Second) } } func main() { ch := make(chan string) for i := 1; i <= 3; i++ { go worker(i, ch) // 複数のゴルーチンを起動 } for i := 0; i < 9; i++ { // 全てのメッセージを受信 fmt.Println(<-ch) } }
この例では、3つのゴルーチンがそれぞれデータを送信します。
メイン関数では、チャネルからすべてのメッセージを受信して出力します。
ここでは、9回データを受信するループを使用しています。
Go言語では、これらの基本的な概念を利用して、効率的な並行処理を行うことができます。
ゴルーチンとチャネルをうまく活用することで、複雑な並行処理をシンプルに実装することが可能です。