[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(分散): ...
随机推荐
- COPY, RETAIN, ASSIGN , READONLY , READWRITE,STRONG,WEAK,NONATOMIC整理--转
copy:建立一个索引计数为1的对象,然后释放旧对象 对NSString 对NSString 它指出,在赋值时使用传入值的一份拷贝.拷贝工作由copy方法执行,此属性只对那些实行了NSCopying协 ...
- mysql索引命中规则
转于:https://blog.csdn.net/claram/article/details/77574600 首先明确:为什么要用联合索引? 对于查询语句“SELECT E.* FROM E WH ...
- sql 删除重复数据
DELETE a FROM tbBuilding a WHERE EXISTS (SELECT 1 FROM tbBuilding b WHERE b.Province = a.Province AN ...
- NYOJ 题目42 一笔画问题
一笔画问题 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用一笔画下 ...
- 李开复:AlphaGo 若打败了世界冠军,意味着什么?
创新工场董事长李开复在知乎就AlphaGo与李世石的人机大战发表了自己看法,他认为四个月前的AlphaGo击败李世石基本不可能,不过这四个月AlphaGo进步很多,比赛应该很精彩.但是,无论这次结果如 ...
- hasChildNodes()方法,nodeName、nodeValue、nodeType介绍
Document对象的使用:hasChildNodes()方法,nodeName.nodeValue.nodeType的简单介绍 一.hasChildNodes() 说明: (1) 该方法 ...
- 原生JS--各种兼容性写法总结
<script> var oEvent = evt || event; ========================================================== ...
- dirname, basename - 分析路径成员
总览 (SYNOPSIS) #include <libgen.h> char *dirname(char *path); char *basename(char *path); 描述 (D ...
- ACCEPT详解
NAME 名称 accept - 在一个套接字上接收一个连接 SYNOPSIS 概述 #include <sys/types.h> #include <sys/socket.h> ...
- window.onload和DOMContentLoaded的区别
一.何时触发这两个事件? 1.当 onload 事件触发时,页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了. 2.当 DOMContentLoaded 事件触发时,仅当DOM加载完 ...