Goroutine
- 檢查有沒有 race condition
go run -race main.go
WaitGroup
用於等待一系列的 goroutine 完成任務
方式:communicating by sharing memory
常用方法
Add: 在 main goroutine 中呼叫
Done: 在其它新建的 goroutine 中呼叫
Wait: 可以 block 直到其他 goroutine 完成
Example
- WaitGroup 全域宣告
package main
import (
"fmt"
"sync"
)
var (
wg sync.WaitGroup
)
func main() {
wg.Add(1)
go compute(5)
fmt.Println("Hello")
wg.Wait()
}
func compute(number int) {
total := 0
for i := 0; i < number; i++ {
total += i
}
fmt.Println(total)
wg.Done()
} - WaitGroup 區域宣告,要傳
pointer
進去package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
wg.Add(1)
go compute(5, &wg)
fmt.Println("Hello")
wg.Wait()
}
// wg 要傳 pointer,才會改到同一個
func compute(number int, wg *sync.WaitGroup) {
total := 0
for i := 0; i < number; i++ {
total += i
}
fmt.Println(total)
wg.Done()
}
Channel
- share memory by communicating
有分以下兩種:
- Unbuffered Channel 讀寫要在不同 goroutine
package main
import (
"fmt"
)
func main() {
ch := make(chan int)
go compute(5, ch)
result := <-ch
fmt.Println("receive:", result)
}
func compute(number int, ch chan<- int) {
total := 0
for i := 0; i < number; i++ {
total += i
}
ch <- total
} - Buffered Channel 只要容量沒滿,就可以一直塞東西進去,可以在同一個 goroutine 一直讀寫此範例不會 block,true 丟進去 channel 後,就直接結束,不會印出任何東西
package main
import "fmt"
func main() {
c := make(chan bool, 1)
go func() {
fmt.Println("hello world")
<-c
}()
c <- true
}
close
: 表示 channel 不能再被寫入,可讀取
- Close (待補齊!!) channel 取值時,可以有第二個參數
ok
,來判斷 channel 是否 closeresult, ok := <-c
if ok {
fmt.Println("is open")
} else {
fmt.Println("is close")
}有無 close,讀值 > 存值
close
not close