原理:
每一個goroutine都往一個channel裏寫入一個值,而後咱們去遍歷這個管道的數值,因爲不帶緩衝區,那麼必須等到寫入端寫入一個值後,for循環才能循環下去。這樣等循環完成後,那麼goroutine也都執行完成了。
實現前提:goroutine必須往channel寫入一個值,不然for循環的時候會報deadlock的錯誤!
代碼以下所示:線程
// main package main import ( "fmt" "time" ) func process(i int, ch chan bool) { fmt.Println("started Goroutine ", i) time.Sleep(2 * time.Second) fmt.Printf("GoRoutine %d ended\n", i) ch <- true //寫入一個值,必須寫入 } func main() { no := 3 exitChan := make(chan bool, no) for i := 0; i < no; i++ { go process(i, exitChan) } for i := 0; i < no; i++ { // 遍歷這個channel <-exitChan } fmt.Println("all goroutines are done!") }
先說說WaitGroup的用途:它可以一直等到全部的goroutine執行完成,而且阻塞主線程的執行,直到全部的goroutine執行完成。
WaitGroup總共有三個方法:Add(delta int)、Done()、Wait()。簡單的說一下這三個方法的做用。code
package main import ( "fmt" "sync" "time" ) func process(i int, wg *sync.WaitGroup) { fmt.Println("started Goroutine ", i) time.Sleep(2 * time.Second) fmt.Printf("Goroutine %d ended\n", i) wg.Done() } func main() { no := 10 var wg sync.WaitGroup for i := 0; i < no; i++ { wg.Add(1) go process(i, &wg) } wg.Wait() fmt.Println("all goroutines are done!") }