golang中四种方式实现子goroutine与主协程的同步
如何实现子goroutine与主线程的同步
第一种方式:time.sleep(),这种方式很太死板,就不演示了。
第二种方式:使用channel机制,每个goroutine传一个channel进去然后往里写数据,在再主线程中读取这些channel,直到全部读到数据了子goroutine也就全部运行完了,那么主goroutine也就可以结束了。这种模式是子线程去通知主线程结束。
package mainimport ( "fmt")func main() { var chanTest = make(chan int) var chanMain = make(chan int) go func() { for i := 0; i < 20; i++ { chanTest <- i fmt.Println("生产者写入数据", i) } close(chanTest) }() go func() { for v := range chanTest { fmt.Println("\t消费者读出数据", v) } chanMain <- 666 }() go func() { for v := range chanTest { fmt.Println("\t\t消费者读出数据", v) } chanMain <- 666 }() <-chanMain <-chanMain }
第三种方式:使用context中cancel函数,这种模式是主线程去通知子线程结束。
package mainimport ( "context" "fmt" "time")func gen(ctx context.Context) <-chan int { dst := make(chan int) n := 1 go func() { for { select { case <-ctx.Done(): fmt.Println("i exited") return // returning not to leak the goroutine case dst <- n: n++ } } }() return dst }func test() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() // cancel when we are finished consuming integers intChan := gen(ctx) for n := range intChan { fmt.Println(n) if n == 5 { break } } }func main() { test() time.Sleep(time.Hour) }
第四种方式:sync.WaitGroup模式,Add方法设置等待子goroutine的数量,使用Done方法设置等待子goroutine的数量减1,当等待的数量等于0时,Wait函数返回。