Go初心者の並行処理入門
Go初心者のための並行処理入門
Goは軽量スレッドであるゴルーチンを使って、並行処理を簡単に実装できます。並行処理は複数のタスクを同時に実行することで、CPUやI/Oの待ち時間を短縮し、アプリケーションの応答性を向上させます。Go初心者が最初に覚えておくべきポイントは、goroutineは関数呼び出しのように簡単に起動でき、内部でスレッドプールが管理してくれることです。
以下は、簡単な並行処理の例です。2つのgoroutineを起動し、チャネルで結果を受け取ります。
package main
import (
"fmt"
"time"
)
func worker(id int, ch chan int) {
time.Sleep(time.Duration(id) * time.Second)
ch <- id
}
func main() {
ch := make(chan int, 2)
go worker(1, ch)
go worker(2, ch)
for i := 0; i < 2; i++ {
fmt.Println("Result:", <-ch)
}
}
ゴルーチンとgoroutineの基本
ゴルーチンはGoの軽量スレッドで、goroutineというキーワードで起動します。goroutineはスタックが自動で伸縮し、数十万個まで起動可能です。goroutineを起動するには go キーワードを関数呼び出しの前に付けるだけです。
goroutineは非同期に実行されるため、呼び出し元のコードはすぐに次の行へ進みます。非同期処理と並列実行は似ているようで、実際には並列実行は複数のCPUコアで同時に動くことを意味します。Goはデフォルトでマルチコアを活用し、goroutineを複数のスレッドに分散します。
goroutineの同期にはチャネルやWaitGroupが便利です。チャネルはデータの送受信を安全に行うための通信手段で、WaitGroupは複数のgoroutineが完了するまで待機するために使います。
非同期と並列実行の違い
非同期は「タスクを開始してすぐに次の処理へ進む」ことを指し、並列実行は「複数のタスクを同時に実行する」ことです。Goではgoroutineを使うことで非同期と並列実行の両方を簡単に実装できます。
例えば、HTTPリクエストを複数同時に送る場合、goroutineを使って非同期にリクエストを発行し、チャネルで結果を集約します。これにより、I/O待ち時間を短縮し、全体のレスポンスタイムを改善できます。
以下は非同期HTTPリクエストの例です。
package main
import (
"fmt"
"net/http"
"sync"
)
func fetch(url string, wg *sync.WaitGroup, ch chan string) {
defer wg.Done()
resp, err := http.Get(url)
if err != nil {
ch <- fmt.Sprintf("Error: %v", err)
return
}
ch <- fmt.Sprintf("Fetched %s: %d", url, resp.StatusCode)
}
func main() {
urls := []string{
"https://example.com",
"https://golang.org",
}
var wg sync.WaitGroup
ch := make(chan string, len(urls))
for _, url := range urls {
wg.Add(1)
go fetch(url, &wg, ch)
}
wg.Wait()
close(ch)
for msg := range ch {
fmt.Println(msg)
}
}
コンカレンシー設計のベストプラクティス
Goで安全かつ効率的にコンカレンシーを設計するためのポイントをまとめます。
- チャネルは型安全で、データの送受信を明示的に管理できるため、競合状態を防止します。
- WaitGroupを使ってgoroutineの終了を待機し、リソースリークを防ぎます。
- select文で複数チャネルを同時に待機し、タイムアウトやキャンセルを実装します。
- goroutineの数は必要に応じて制限し、過剰なスレッド生成を避けます。必要なら
runtime.GOMAXPROCSでCPU数を設定します。 - エラーハンドリングは必ず行い、失敗したgoroutineを適切にクリーンアップします。
これらのベストプラクティスを守ることで、Go初心者でも安全に並行処理を実装でき、軽量スレッドを活用した非同期・並列実行が可能になります。
コメント
コメントを投稿