GOを1から学ぶ #7
初めに
こんにちは!技術スタック的には、フロントよりですが、GOを学ぶ機会があったので、その記録を取りたいと思いこの記事を書いてます。(初心者のため優しい目で見てください)
今回は、以下について簡単にまとめます。
- 並行処理について
Goroutine(ゴルーチン)とは?
Goroutine(ゴルーチン)は、関数やメソッドを同時に実行(並行処理) するための仕組み。goを関数の前につけるだけで、新しいGoroutineが作成可能。
基本構文
go 関数名(引数)
具体的な例:2つのタスクを並行実行する
package main
import (
"fmt"
"time"
)
func task1() {
for i := 0; i < 5; i++ {
fmt.Println("Task 1 -", i)
time.Sleep(100 * time.Millisecond)
}
}
func task2() {
for i := 0; i < 5; i++ {
fmt.Println("Task 2 -", i)
time.Sleep(150 * time.Millisecond)
}
}
func main() {
go task1() // 並行実行
go task2() // 並行実行
time.Sleep(1 * time.Second) // 並行処理が終わるまで待機
fmt.Println("All tasks completed")
}
実行結果
Task 2 - 0
Task 1 - 0
Task 1 - 1
Task 2 - 1
Task 1 - 2
Task 1 - 3
Task 2 - 2
Task 1 - 4
Task 2 - 3
Task 2 - 4
All tasks completed
sync.WaitGroup
sync.WaitGroup とは
Goでは go キーワードを使って複数の処理(ゴルーチン)を並行して実行可能だが、すべてのゴルーチンが終わるまで待ちたい場合に sync.WaitGroup が使われる。
たとえば、3つのゴルーチンで並列処理を行い、それらが全部終わってから次の処理をしたい場合などに役立つ。Add() で待つゴルーチン数を指定し、各ゴルーチンで Done() を呼び、最後に Wait() で完了を待つ。
基本的な構文
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup // WaitGroup を作成
wg.Add(2) // ゴルーチンを2つ待つ
go func() {
defer wg.Done() // ゴルーチン1の終了を通知
fmt.Println("ゴルーチン1の処理")
}()
go func() {
defer wg.Done() // ゴルーチン2の終了を通知
fmt.Println("ゴルーチン2の処理")
}()
wg.Wait() // すべてのゴルーチンの完了を待つ
fmt.Println("すべての処理が完了しました")
}
実行結果
ゴルーチン2の処理
ゴルーチン1の処理
すべての処理が完了しました
具体的な例
package main
import (
"fmt"
"sync"
"time"
)
func task1(wg *sync.WaitGroup) {
defer wg.Done() // 処理が終わったら Done を呼ぶ
for i := 0; i < 5; i++ {
fmt.Println("Task 1 -", i)
time.Sleep(100 * time.Millisecond)
}
}
func task2(wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < 5; i++ {
fmt.Println("Task 2 -", i)
time.Sleep(150 * time.Millisecond)
}
}
func main() {
var wg sync.WaitGroup
wg.Add(2) // 並行実行するタスクの数を指定
go task1(&wg) // Goroutine を起動
go task2(&wg)
wg.Wait() // すべての Done を待つ
fmt.Println("All tasks completed")
}
実行結果
Task 2 - 0
Task 1 - 0
Task 1 - 1
Task 2 - 1
Task 1 - 2
Task 1 - 3
Task 2 - 2
Task 1 - 4
Task 2 - 3
Task 2 - 4
All tasks completed
sync.WaitGroup使用の判断
Channel(チャネル)とは?
Go言語の Channel(チャネル) とは、ゴルーチン(goroutine)間でデータをやり取りするための仕組み。
チャネルの概要
チャネルはパイプのようなもので、あるゴルーチンがチャネルにデータを送信し、別のゴルーチンがそのデータを受信する。また、チャネルはある特定の型の値だけを送受信できます。
基本構文
// チャネルの作成
ch := make(chan int)
// チャネルに値を送信
ch <- 10
// チャネルから値を受信
x := <-ch
ゴルーチンとチャネルの組み合わせ
package main
import (
"fmt"
)
// 数字を2倍にしてチャネルに送る関数
func double(num int, ch chan int) {
result := num * 2
ch <- result // チャネルに送信
}
func main() {
ch := make(chan int) // チャネル作成
go double(5, ch) // ゴルーチンで関数を実行
result := <-ch // チャネルから値を受信(完了するまで待つ)
fmt.Println(result) // 出力: 10
}
実行結果
10
Discussion