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函数返回。