zoukankan      html  css  js  c++  java
  • go之无缓冲channel(通道)和有缓冲channel(通道)

    channel
    我们先来看一下通道的解释:
    channel是Go语言中的一个核心类型,可以把它看成管道。并发核心单元通过它就可以发送或者接收数据进行通讯,这在一定程度上又进一步降低了编程的难度。
    channel是一个数据类型,主要用来解决go程的同步问题以及协程之间数据共享(数据传递)的问题。
    goroutine运行在相同的地址空间,因此访问共享内存必须做好同步。goroutine 奉行通过通信来共享内存,而不是共享内存来通信。
    引用类型 channel可用于多个 goroutine 通讯。其内部实现了同步,确保并发安全。


    定义channel和使用
    和map类似,channel也一个对应make创建的底层数据结构的引用。
    当我们复制一个channel或用于函数参数传递时,我们只是拷贝了一个channel引用,因此调用者和被调用者将引用同一个channel对象。和其它的引用类型一样,channel的零值也是nil。
    定义一个channel时,也需要定义发送到channel的值的类型。channel可以使用内置的make()函数来创建:
    我们先来看一段代码

    package main
    import "fmt"
    func main(){
    ch:=make(chan int) //这里就是创建了一个channel,这是无缓冲管道注意
    go func(){ //创建子go程
    for i:=0;i<6;i++{
    ch<-i //循环写入管道
    fmt.Println("写入",i)
    }
    }()

    for i:=0;i<6;i++{ //主go程
    num:=<-ch //循环读出管道
    fmt.Println("读出",num)
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    我们先看一下运行结果再来看代码:

    我们在代码中 先创建了一个匿名函数的子go程,和main的主go程一起争夺cpu,但是我们在里面创建了一个管道,无缓冲管道有一个规则那就是必须读写同时操作才会有效果,如果只进行读或者只进行写那么会被阻塞,被暂时停顿等待另外一方的操作,在这里我们定义了一个容量为0的通道,这就是无缓冲通道,如下图

    无缓冲通道就是这样,一次只能传输一个数据
    总结一下就是无缓冲特性:
    同一时刻,同时有 读、写两端把持 channel。
    如果只有读端,没有写端,那么 “读端”阻塞。
    如果只有写端,没有读端,那么 “写端”阻塞。
    读channel: <- channel
    写channel: channel <- 数据

    有缓冲channel
    如图所示:

    . 在第 1 步,右侧的 goroutine 正在从通道接收一个值。
    在第 2 步,右侧的这个 goroutine独立完成了接收值的动作,而左侧的 goroutine 正在发送一个新值到通道里。
    在第 3 步,左侧的goroutine 还在向通道发送新值,而右侧的 goroutine 正在从通道接收另外一个值。这个步骤里的两个操作既不是同步的,也不会互相阻塞。
    最后,在第 4 步,所有的发送和接收都完成,而通道里还有几个值,也有一些空间可以存更多的值。
    有缓冲通道就是图中所示,一方可以写入很多数据,不用等对方的操作,而另外一方也可以直接拿出数据,不需要等对方写,但是注意一点(如果写入的一方把channel写满了,那么如果要继续写就要等对方取数据后才能继续写入,这也是一种阻塞,读出数据也是一样,如果里面没有数据则不能取,就要等对方写入),而有缓冲channel定义也比较简单

    ch:=make(chan int,10)//chan int 只能写入读入int类型的数据,10代表容量为10.
    1
    这里用了自动推导类型来声明了一个有缓冲的channel
    总结起来就是:
    channel 中自带缓冲区。创建时可以指定缓冲区的大小。
    w:直到缓冲区被填满后,写端才会阻塞。
    r:缓冲区被读空,读端才会阻塞。
    len:代表缓冲区中,剩余元素个数,
    cap:代表缓冲区的容量。
    在这里可以举个小小的例子来解释一下有缓冲channel和无缓冲channel
    同步通信: 数据发送端,和数据接收端,必须同时在线。 —— 无缓冲channel
    打电话。打电话只有等对方接收才会通,要不然只能阻塞

    异步通信:数据发送端,发送完数据,立即返回。数据接收端有可能立即读取,也可能延迟处理。 —— 有缓冲channel 不用等对方接受,只需发送过去就行
    发信息。短信。
    是不是很形象呢
    下一节将讲解一下channel常见的陷阱以及关闭channel


    ————————————————
    版权声明:本文为CSDN博主「sgsgy5」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/sgsgy5/article/details/82054902

  • 相关阅读:
    js赋值的两种方式
    Object.defineProperty熬夜整理的用法,保证你看的明白!
    2019CCSP A. 摘水果(拓扑排序)
    Codeforces Round #748 (Div. 3) E. Gardener and Tree(树的直径)
    开博了
    IBM MQSeries的触发(Triggering)机制
    重定向 1>&2 2>&1
    Oracle SQL Loader Command
    CVS Change Password
    Some useful Regular Expression for Web UI Validation
  • 原文地址:https://www.cnblogs.com/saolv/p/12000367.html
Copyright © 2011-2022 走看看