go之无缓冲channel(通道)和有缓冲channel(通道)

摘要:
channel我们先来看一下通道的解释:channel是Go语言中的一个核心类型,可以把它看成管道。引用类型channel可用于多个goroutine通讯。定义channel和使用和map类似,channel也一个对应make创建的底层数据结构的引用。定义一个channel时,也需要定义发送到channel的值的类型。在这里可以举个小小的例子来解释一下有缓冲channel和无缓冲channel同步通信:数据发送端,和数据接收端,必须同时在线。——无缓冲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

免责声明:文章转载自《go之无缓冲channel(通道)和有缓冲channel(通道)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇mysql中的union用法以及子查询综合应用openlayers4 入门开发系列结合 echarts4 实现散点图(附源码下载)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

socks5代理使用和安装配置

如上图所示,选择Socks5代理的类型,然后正确填写Socks代理服务器的IP、端口、用户和密码。示例3:Firefox代理Firefox浏览器连接设置可以配置为使用Socks5代理。问题是它没有提供用户输入和密码验证项目。如上图所示,客户端的默认规则是所有应用程序都使用Socks代理,这就是为什么Firefox透明地使用Socks,而不进行任何代理设置。P...

Python3 读取和写入excel

/py_工作/销售/包括/天气。csv'_工作簿函数读取并返回所有工作表● 以列表形式读取_仅:判断是否读取_仅以模式打开Excel文档● 编码:...

PLSQL常用配置之窗口/版面保存、SQL格式化/美化、SQL注释去掉注释等快捷键配置、登陆历史修改配置

//Blog.csdn.net/eyeidolon/article/details/8251791 PLSQL常用配置的快捷键配置,如窗口/布局保存、SQL格式化/美化和SQL注释删除,以及登录历史修改1的配置。PL/SQLDeveloper记住登录密码当使用PL/SQLDeveloper时,默认情况下PL/SQLDeveloper会执行此窗口中的所有SQL...

iTerm2 配色方案(转)

ITerm2配色方案(噢,我的zsh&amp;Powerline)item2.png转到官方网站下载ITerm2,并以全黑色背景打开它。屏幕截图2017-08-01下午5.45.28点。Pngsolarized可以说是目前网络上最流行的配色方案,我个人认为比较这种配色更好。第一种方法:打开iTerm2首选项、配置文件/颜色,然后直接选择Solariz...

JS前端数据多条件筛选(商品搜索)

有时候也会需要在前端进行数据筛选,增强交互体验。当数据可用的筛选条件较多时,把逻辑写死会给后期维护带来很大麻烦。进行商品按条件筛选主要是利用Arrary.prototype.filter对数组元素进行遍历检查,返回一个符合检查条件的新数组,不会改变原数组。为了能自动适配不同的筛选条件,将筛选条件分为两个大类,一个是区间类型rangesFilter,如:品牌、...

001_Three.js中的跨域问题

】当请求的资源和请求脚本不在同一域中时,将发生跨域。有关详细信息,请参见链接。这是一个需要进一步考虑的问题。它是一个装载机。它加载本地资源。为什么要跨域请求?...