go的goroutine 调用和channel的使用

开启goroutine :

var lwg sync.WaitGroup
func main() {
    go lian1()
    go lian2()
    go lian3()
    lwg.Add(3)

    fmt.Println("main")
    lwg.Wait() //等待其他协程结束
}

func lian1() {
    fmt.Println("lian1")
    lwg.Done()
}

func lian2() {
    fmt.Println("lian2")
    lwg.Done()
}

func lian3() {
    fmt.Println("lian3")
    lwg.Done()
}


无缓存的通道:
func main() {
    //无缓冲的通道,阻塞的通道
    se := make(chan int) //有缓存的通道可以在本goroutines或者其他goroutines使用,但是没有缓存的通道只能和其他goroutines一起使用并造成串行
    go lian4(se)         //没有缓存的通道,只能先调用取值的goroutines,后面才能发送,如果先发送再取值会死锁
    se <- 10             //发送
    fmt.Println("发送成功")
    go lian5()
    go lian6()
    fmt.Println("main")
    time.Sleep(time.Millisecond * 5)
}

func lian4(se chan int) {
    fmt.Println("准备取值")
    res := <-se //没有缓存的通道,下一步一定是在这里取值之后才到其他地方,但是并不是一定要完整执行完当前方法才到其他地方,只是一定会到取值的位置而已
    fmt.Println("接收成功", res)
    fmt.Println("lian4")
}

func lian5() {
    fmt.Println("lian5")
}

func lian6() {
    fmt.Println("lian6")
}


有缓存的通道:
func main() {
    ch := make(chan int, 2)
    ch <- 1
    ch <- 2
    close(ch) //在接收方明确等待通道关闭的信号时才需要执行关闭操作,建议手动执行关闭操作,不然循环取值的时候会死锁;通道关闭了还是能取值,但是不能发送值
    lian7(ch)
}

func lian7(ch chan int) {
    for v := range ch { //当通道被关闭后,会在通道内的所有值被接收完毕后会自动退出循环
        fmt.Println(v)
    }
}

 

多路复用:
func main() {
    ch1 := make(chan int, 10)
    ch2 := make(chan int, 10)
    ch3 := make(chan int, 10)
    lian9(ch1)
    lian10(ch2)
    lian11(ch3)

    lian8(ch1, ch2, ch3)
}

func lian8(ch1 chan int, ch2 chan int, ch3 chan int) {
    //随机输出一个
    select {
    case data := <-ch1:
        fmt.Println("ch1:", data)
    case data := <-ch2:
        fmt.Println("ch2:", data)
    case ch3 <- 10:
        data := <-ch3
        fmt.Println("ch3:", data)
    }
}

func lian9(ch chan int) <-chan int {
    ch <- 10
    return ch
}

func lian10(ch chan int) <-chan int {
    ch <- 12
    return ch
}

func lian11(ch chan int) <-chan int {
    ch <- 14
    return ch
}

 



posted @ 2022-06-09 14:38  1O(∩_∩)O1  阅读(65)  评论(0编辑  收藏  举报