原理:
每一个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!") }