golang 基礎(30) WaitGroup

golang_real.jpg
golang中有2種方式同步程式,一種使用channel,另一種使用鎖機制。sync.WaitGroup只有3個方法,Add(),Done(),Wait()。其中Done()是Add(-1)的別名。簡單的來說,使用Add()新增計數,Done()減掉一個計數,計數不為0, 阻塞Wait()的執行。
func main(){ go foo() go bar() } func foo(){ for i := 0; i < 45; i++{ fmt.Println("Foo",i) } } func bar(){ for i := 0; i < 45; i++{ fmt.Println("Bar:",i) } }
var wg sync.WaitGroup func main(){ wg.Add(2) go foo() go bar() wg.Wait() } func foo(){ for i := 0; i < 45; i++{ fmt.Println("Foo",i) } wg.Done() } func bar(){ for i := 0; i < 45; i++{ fmt.Println("Bar:",i) } wg.Done() }

th (1).jpg
waitGroup 新增 2 兩個然後直到執行到 0 ,排序是不確定,這裡複習一下介面引用的呼叫方式。
func (wg *WaitGroup) Add(delta int)
package main import( "fmt" "math" ) type circle struct{ radius float64 } type shape interface{ area() float64 } func (c *circle) area() float64{ return math.Pi * c.radius * c.radius } func info(s shape){ fmt.Println("area",s.area()) } func main(){ c := circle{5} info(c) }
circle does not implement shape (area method has pointer receiver)
func main(){ c := &circle{5} info(c) }
在 go 語言中可以為一個常量 42 定義時候指定型別或者不指定型別。在定義型別時候在 go 語言還不確定是否分配記憶體,所以在接受指標型別的情況我們不能使用值傳遞。
func foo(){ for i := 0; i < 45; i++{ fmt.Println("Foo",i) time.Sleep(time.Duration(3.*time.Millisecond)) } wg.Done() } func bar(){ for i := 0; i < 45; i++{ fmt.Println("Bar:",i) time.Sleep(time.Duration(20.*time.Millisecond)) } wg.Done() }
加入休眠,當任務休眠時候,空閒下來 CPU 就可以去處理其他任務。

th (3).jpg

concurrency_vs_parallelism.jpeg
從圖可以清晰地看出 concurrency 和 parallelism 的區別,一個恰當例項就是我們喝咖啡和談話,concurrency 就是類似我們一邊和咖啡一邊打電話。類似同時進行,切實是在兩者之間不斷切換。

th (2).jpg