概要
goroutineの意味と使用例を説明
目的
- goroutineを使う際の備忘録として機能すること
背景
- golangの特徴とも言える機能を試してみたい
- どれくらい処理速度に影響がでるのか試してみたかった
実際に使ってみた
gorouineを使わない
package main
import (
"fmt"
"time"
)
func normal(s, a string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
fmt.Println(a)
}
}
func main() {
normal("hello", "world")
}
hello
world
hello
world
hello
world
hello
world
hello
world
goroutineを使う
package main
import (
"fmt"
"time"
)
func goroutine(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func normal(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go goroutine("world")
normal("hello")
}
hello
world
world
hello
hello
world
world
hello
hello
並列で処理してる!
sync.WaitGroupを使って処理の完了を保証
何が問題なのか
- time.Sleep(100 * time.Millisecond)で処理の終了を待っているため処理に遅延が発生している
- 明示的に処理を待つのではなく、処理の完了と同時に次の処理へ移行する方が望ましい
sync.WaitGroupを使ってみた
package main
import (
"fmt"
"sync"
)
// wgのポインタを宣言
func goroutine(s string, wg *sync.WaitGroup) {
for i := 0; i < 5; i++ {
fmt.Println(s)
}
// 処理が終わるとDoneすることを宣言
wg.Done()
}
func normal(s string) {
for i := 0; i < 5; i++ {
fmt.Println(s)
}
}
func main() {
// sync.WaitGroupを宣言
var wg sync.WaitGroup
// 並列処理が一つあることを明示
wg.Add(1)
// goroutineにwgのアドレスを持たせる
go goroutine("world", &wg)
normal("hello")
// mainの処理はDoneするまで待つように指示
wg.Wait()
}
hello
hello
hello
hello
hello
world
world
world
world
world