go-channel和goroutine结合使用

通道(channel)

通道(channel)是用来传递数据的一个数据结构。

通道可用于两个 goroutine 之间通过传递一个指定类型的值来同步运行和通讯。操作符 <- 用于指定通道的方向,发送或接收。如果未指定方向,则为双向通道。
这个意思很明确,goroutine是支持多线程,channel作为一个管道接收数据输出数据,遵循先进先出原则。

来个例子感受下,创建三个goroutine,都传入channel值

func main() {

    ch := make(chan string)

    go chanaction1(ch)
    time.Sleep(time.Second)
    go chanaction2(ch)
    time.Sleep(time.Second)
    go chanaction3(ch)
    x,y,z := <-ch, <-ch, <-ch
    fmt.Println(x,y,z)
}

func chanaction1(ch chan string)  {
    ch <- "1"
}

func chanaction2(ch chan string)  {
    ch <- "2"
}

func chanaction3(ch chan string)  {
    ch <- "3"
}

输出就是:


image.png

这样就可以异步加入channel值了,而且输出顺序和输入顺序一致,但是有人会说,三个协程可能会阻塞,好吧,那我们拿一个协程来试,代码如下:

func main() {

    ch := make(chan string)

    go chanaction1(ch)
    x,y,z := <-ch, <-ch, <-ch
    fmt.Println(x,y,z)
}

func chanaction1(ch chan string)  {
    ch <- "1"
    ch <- "2"
    ch <- "3"
}

重新执行,结果还是输出1,2,3。

一般的协程和channel没有这么简单用法,再举个比较常见的用法:线程阻塞等待channel通道结果,
如,a := <-ch,当通道ch中没有值,则当前协程一直阻塞,直到ch接收新数据,如:执行ch <- 1后,线程不再阻塞,好,在上面的基础添加测试代码

func main() {

    ch := make(chan string)

    go chanaction1(ch)
    x,y,z := <-ch, <-ch, <-ch
    fmt.Println(x,y,z)

    go gorutine2(ch)
    a := <-ch
    fmt.Println(a)
}

func chanaction1(ch chan string)  {
    ch <- "1"
    ch <- "2"
    ch <- "3"
}

func gorutine2(ch chan string)  {
    for i := 0; i<5000; i++ {
        time.Sleep(time.Second *1)
        fmt.Println("----等待----")
        if i>= 5 {
            ch <- "end"
            return
        }
    }
}

看效果:

image.png

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。