[Go]通道(channel)的基本操作
通道类型是Go语言自带的、唯一一个可以满足并发安全性的类型,在声明并初始化一个通道时,需要用到内建函数make,传给make函数的第一个参数应该代表通道的具体类型的类型字面量。
如类型字面量 chan int,其中chan表示通道类型的关键字,而int说明了该通道类型的元素类型。
在初始化通道时,make函数除了必须接受这样的字面量作为参数,还可以接收一个int类型的参数。后者是可选的,用于表示通道的容量(通道最多缓存多少个元素值),不能小于0。当容量为0时称其为非缓冲通道,当容量大于0时,可以称为缓冲通道
一个通道相当于一个先进先出(FIFO)的队列。元素值的发送和接收都需要用到操作符 <-
package main import "fmt" func main() {
ch1 := make(chan int, )
ch1 <-
ch1 <-
ch1 <-
elem1 := <-ch1
fmt.Printf("first element :%v\n", elem1)
}
由于该通道容量为3,所以可以在通道不包含任何元素值的时候,连续地向该通道发送三个值,此时这三个值都会被缓存在通道之中。当从通道接收元素值的时候,同样要用接送操作符 <-
1、对通道的发送和接收操作都有哪些基本的特性?
1)对于同一个通道,发送操作之间是互斥的,接收操作之间也是互斥的
在同一时刻,Go语言的运行时系统只会执行对同一个通道的任意个发送操作中的某一个,知道这个元素值被完全复制进该通道之后,其他针对该通道的发送操作才可能被执行
类似的,在同一时刻,运行时系统也只会执行对同一个通道的任意个接收操作中的某一个,直到这个元素值完全被移除该通道之后,其他针对该通道的接收操作才可能被执行。
另外,对于通道中的同一个元素值来说,发送操作和接收操作也是互斥的,虽会出现正在被复制进通道但还未复制完成的元素值,但此时它绝不会被想接收它的一方看到和取走
并且,元素值从外界进入通道时会被复制,进入通道的并不是接收操作符右边那个元素值,而是它的副本。
2)发送操作和接收操作中对元素值的处理都是不可分割的
不可分割的意思是处理元素值时是一气呵成不会被打断的
发送操作要么还没复制元素值,要么已经复制完毕,绝不会出现只复制一部分的情况
接收操作在准备好元素值的副本之后,一定会删除通道中的原值,绝不会出现通道中仍有残留的情况
对于通道中的桶一个元素值来说,它只可能是某一个发送操作放入的,同时也只可能被某一个接收操作取出
3)发送操作在完成之前会被阻塞,接收操作也是
发送操作包括“复制元素值”和“放置副本通道内部”两个步骤,在这两个步骤完全完成之前,发起这个发送操作的那句代码会一直阻塞在那里,在它之后的代码不会有执行的机会,直到这句代码阻塞解除。在通道完成发送操作之后,运行时系统会通知这句代码所在 的goroutine,以使它去争取继续运行代码的机会
接收操作包括“复制通道内的元素”,“放置副本到接收方”,“删掉原值”三个步骤,同理在这些步骤完全完成之前,发起该操作的代码也会一直阻塞。
2、发送操作和接收操作在什么时候可能被长时间阻塞
1)缓冲通道
如果通道已满,那么对它的所有发送操作都会被阻塞,直到通道中有元素值被接收走。通道会优先通知最早等待的那个发送操作所在的goroutine,通知的顺序总是公平的
如果通道已空,那么对它的所以接收操作都会被阻塞,直到通道中有新的元素值出现,通道会优先通知最早等待的那个接收操作所在的goroutine,通知的顺序总是公平的
2)非缓冲通道
无论发送操作还是接收操作,一开始执行就会被阻塞,直到配对的操作也开始执行。即非缓冲通道是在用同步的方式传递数据,也就是说,只有收发双方对接上了,数据才会被床底,数据是直接从发送方复制到接收方的,中间并不会用非缓冲通道做中转
3)对值为nil的通道
不论它的具体类型是什么,对它的发送操作和接收操作都会永久地处于阻塞状态,它们所属的goroutine中的任何代码,都不会被执行。因此一定要初始化通道
3、发送操作和接收操作在什么时候会引发panic?
对于一个已初始化,但并未关闭的通道来说,收发操作一定不会引发panic,但通道一旦关闭,再对它进行发送操作,就会引发panic。
如果试图关闭一个已经关闭了的通道,也会引发panic
当把接收表达式结果同时赋值给两个变量时,第二个变量的类型就是一定bool类型,它的值如果是False就说明通道已经关闭,并且再没有元素值可取。如果通道关闭时,里面还有元素值未被取出,那么接收表达式的第一个结果仍会是通道中的某一个元素值,而第二个结果值一定会是true
[Go]通道(channel)的基本操作的更多相关文章
- nio再学习之通道channel
通道(Channel):用于在数据传输过程中,进行输入输出的通道,其与(流)Stream不一样,流是单向的,在BIO中我们分为输入流,输出流,但是在通道中其又具有读的功能也具有写的功能或者两者同时进行 ...
- Java NIO中的通道Channel(一)通道基础
什么是通道Channel 这个说实话挺难定义的,有点抽象,不过我们可以根据它的用途来理解: 通道主要用于传输数据,从缓冲区的一侧传到另一侧的实体(如文件.套接字...),反之亦然: 通道是访问IO服务 ...
- NIO之通道(Channel)的原理与获取以及数据传输与内存映射文件
通道(Channel) 由java.nio.channels包定义的,Channel表示IO源与目标打开的连接,Channel类似于传统的“流”,只不过Channel本身不能直接访问数据,Channe ...
- 理解CNN中的通道 channel
在深度学习的算法学习中,都会提到 channels 这个概念.在一般的深度学习框架的 conv2d 中,如 tensorflow .mxnet ,channels 都是必填的一个参数. channel ...
- go中的数据结构通道-channel
1. channel的使用 很多文章介绍channel的时候都和并发揉在一起,这里我想把它当做一种数据结构来单独介绍它的实现原理. channel,通道.golang中用于数据传递的一种数据结构.是g ...
- 详解 通道 (Channel 接口)
在本篇博文中,本人主要讲解NIO 的两个核心点 -- 缓冲区(Buffer) 和 通道 (Channel)之一的 缓冲区(Buffer), 有关NIO流的其他知识点请观看本人博文<详解 NIO流 ...
- Java NIO之通道Channel
channel与流的区别: 流基于字节,且读写为单向的. 通道基于快Buffer,可以异步读写.除了FileChannel之外都是双向的. channel的主要实现: FileChannel Data ...
- go实例之轻量级线程goroutine、通道channel与select
1.goroutine线程 goroutine是一个轻量级的执行线程.假设有一个函数调用f(s),要在goroutine中调用此函数,请使用go f(s). 这个新的goroutine将与调用同时执行 ...
- Java-NIO(四):通道(Channel)的原理与获取
通道(Channel): 由java.nio.channels包定义的,Channel表示IO源与目标打开的连接,Channel类似于传统的“流”,只不过Channel本身不能直接访问数据,Chann ...
- Java NIO中的通道Channel(二)分散/聚集 Scatter/Gather
什么是Scatter/Gather scatter/gather指的在多个缓冲区上实现一个简单的I/O操作,比如从通道中读取数据到多个缓冲区,或从多个缓冲区中写入数据到通道: scatter(分散): ...
随机推荐
- popoverController使用注意--转
一.设置尺寸 提示:不建议,像下面这样吧popover的宽度和高度写死. 1 //1.新建一个内容控制器 2 YYMenuViewController *menuVc=[[YYMenuViewCont ...
- json2.js 源码解读
这一部分是对Date String Number Boolean扩展toString方法,Date的toString是返回UTC格式的字符串,而后面几个是返回原始值. function f(n) {/ ...
- Linux--NiaoGe-Service-01
安装环境介绍 CentOS 6.9_x86_64 我们选择的是基本安装,也即“Basic Server”. 安装完成后重启来到(runlevel 3)纯文本界面. 例题 批量创建账号:假设有5个账号x ...
- 项目错误提示Multiple markers at this line
新安装个Myeclipse,导入以前做的程序后程序里好多错,第一行提示: Multiple markers at this line - The type java.lang.Obje ...
- asp.net core教程 (一)
Asp.Net Core简介 ASP.NET Core 是一个全新的开源.跨平台框架,可以用它来构建基于网络连接的现代云应用程序,比如:Web 应用,IoT(Internet Of Things,物联 ...
- 浏览器的差距、ie6 ie7 ie8、符号、html css、BFC、
1.浏览器的差距 浏览器默认的字体是16px,谷歌的最小字体是12px,其他是10px 2.ie6.ie7.ie8. hack:就是针对不同的浏览器去不同的html,css样式,从而让各个浏览器能达到 ...
- Android基础夯实--重温动画(二)之Frame Animation
心灵鸡汤:天下事有难易乎,为之,则难者亦易矣:不为,则易者亦难矣. 摘要 当你已经掌握了Tween Animation之后,再来看Frame Animation,你就会顿悟,喔,原来Frame Ani ...
- pre-network android 网络优化预加载框架
网络优化是所有app开发中非常重要的一部分,如果将网络请求前置就是在点击跳转activity之前开始网络加载那么速度将会有质的提升.也就是网络预先加载框框架. 网络预加载框架,监听式网络前置加载框架- ...
- Windows Server 启用匿名共享
1.开始 → 运行 → gpedit.msc,打开组策略编辑器: 2.依次展开"计算机配置" → "windows设置" → "安全设置" ...
- html文本溢出显示省略字符的两种常用方法
方法一:使用CSS溢出省略的方式解决 解决效果如下: css代码: display: -webkit-box; display: -moz-box; white-space: pre-wrap; wo ...