理解golang中的channel
channel是goroutine之间的通信机制。可以类比线程间的通信,线程间的通信有多种方式,比如线程上下文、共享内存、IPC通信、socket实现不同机器间的通信。
channel用起来很简单,绑定一个变量,一端往里塞,一端从里面取。我把它理解为接收端启动了一个类似HTTP服务器的东西,发送端往接收端的HTTP服务器发送一条get请求,接收端就收到了,可以解析拿到请求的参数再做要做事情。
如何创建一个channel?
ch := make(chan int) // 创建一个channel
channel是有类型的,int类型的channel就只能传输int类型的数据,想传输string类型的数据创建的时候需要改为 ch := make(chan string)
如何向channel发送数据?
ch <- 123 // 向int类型的channel发送数据123
如何从接收数据?
x = <- ch
或者也可以不要接受对象
<- ch
可以看出,不管是发送还是接收数据,用的都是 <- ,区别在于 <- 指向的对象是普通变量还是channel,如果是channel被指向就是给channel发送数据,如果是普通变量被指向就是从channel中取数据。
channel是可以带缓存的,我们前面创建的channel是没带缓存的。有缓存和无缓存有什么区别吗?
缓存的存在是为了抹平channel发送端和接收端速度不匹配造成的资源浪费。比方说一个人扔苹果,一个人接苹果,扔的人扔的速度比接的人速度快,这时候苹果就会掉到地上了。如果没有缓存,我们该如何解决这个问题?
可以用阻塞的方式来解决。比方说我们约定,扔苹果的人在接苹果的人没有接到苹果之前,不能继续扔苹果了,要等到接苹果的人接到苹果才可以继续。这就是阻塞。
在无缓存的情况下,channel发送端在发送后会阻塞,直到发送的数组在channel里被别人接收了才可以继续。反过来如果接收操作先发生,那么接收端会被阻塞,直到它等到channel里传来的数据才恢复。
可以看出,在无缓存的情况下,channel之间的通信是同步的,一个等一个。缓存的出现让channel摆脱了同步,变成了异步的形式。
还是刚刚扔苹果的例子,扔苹果的速度比接苹果的速度快,这次接苹果的人在脚下放了一个框,说“这个框可以装10个苹果,你把苹果都扔到这个框里,我慢慢取。当然如果框里已经有10个苹果的时候,就不能再扔了,只能等到我取出苹果以后再扔。”
这样发送者和接收者的速度差就被缓存减小了一部分,我可以多来一个接收者从框里取苹果来加快接收端的速度。
如何创建一个待缓存的channel?
ch := make(chan int, 10) // 创建一个可以存放10个int型数据的channel
channnel也可以关闭,关闭以后对这个channel的任何发送操作都会导致panic异常,但是还可以从这个channel中接收数据,如果channel里还有之前成功发送的数据,是可以取到的,但是如果channel已经空了,那就将返回一个零值。
关闭channel可以用
close(ch) // 关闭channel
理解golang中的channel的更多相关文章
- 如何理解golang中的nil
nil的奇怪行为 刚接触golang时,发现nil在不同的上下文,行为表现是不同的,并且和其他语言中的表现,也不大相同 实例1:输入true, true, false,不符合传递性 func main ...
- [Go] 理解 golang 中的 nil
nil是什么 相信写过Golang的程序员对下面一段代码是非常非常熟悉的了: if err != nil { // do something.... } 当出现不等于nil的时候,说明出现某些错误了, ...
- golang中的channel
1. 概念 单纯的将函数并发执行是没有意义的,函数与函数之间需要交换数据才能提现并发执行函数的意义虽然可以使用共享内存来进行数据的交换,但是在共享内存在不同的goroutine中容易发生竟态问题,为了 ...
- 理解golang中的function types
先找个例子来看一下: package main import "fmt" // Greeting function types type Greeting func(name st ...
- golang中并发sync和channel
golang中实现并发非常简单,只需在需要并发的函数前面添加关键字"go",但是如何处理go并发机制中不同goroutine之间的同步与通信,golang 中提供了sync包和channel ...
- golang中并发的相关知识
golang中done channel理解:https://segmentfault.com/a/1190000006261218 golang并发模型之使用Context:https://segme ...
- go---weichart个人对Golang中并发理解
个人觉得goroutine是Go并行设计的核心,goroutine是协程,但比线程占用更少.golang对并发的处理采用了协程的技术.golang的goroutine就是协程的实现. 十几个gorou ...
- golang 中 channel 的非阻塞访问方法
在golang中,基本的channel读写操作都是阻塞的,如果你想要非阻塞的,可以使用如下示例: 即只要在select中加入default,阻塞立即变成非阻塞: package main import ...
- 进一步认识golang中的并发
如果你成天与编程为伍,那么并发这个名词对你而言一定特别耳熟.需要并发的场景太多了,例如一个聊天程序,如果你想让这个聊天程序能够同时接收信息和发送信息,就一定会用到并发,无论那是什么样的并发. 并发的意 ...
随机推荐
- 用CIFilter生成QRCode二维码图片
用CIFilter生成QRCode二维码图片 CIFilter不仅仅可以用来做滤镜,它还可以用来生成二维码. CIFilterEffect.h + CIFilterEffect.m // // CIF ...
- XISE菜刀V13.0 官网版 XISE菜刀VIP破解版 XISE官网
诠释: 1. 破解VIP登陆限制 2.去后门 (自查) 下载地址 :https://pan.baidu.com/s/1eR2rUOM 查毒地址:http://a.virscan.org/a3983f3 ...
- Vue.js经典开源项目汇总
Vue.js经典开源项目汇总 原文链接:http://www.cnblogs.com/huyong/p/6517949.html Vue是什么? Vue.js(读音 /vjuː/, 类似于 view) ...
- Java使用iText生成word文件的完美解决方案(亲测可行)
JAVA生成WORD文件的方法目前有以下种: 一种是jacob 但是局限于windows平台 往往许多JAVA程序运行于其他操作系统 在此不讨论该方案 一种是pio但是他的excel处理很程序 wor ...
- 「LG2664 树上游戏」
题目 这真是一道神仙的一批的题目 定义\(s(i,j)\)表示从点\(i\)到点\(j\)经过的颜色数量 设 \[sum_i=\sum_{j=1}^ns(i,j)\] 求出所有的\(sum_i\) 考 ...
- UVA151 Power Crisis
嘟嘟嘟 这道题被评为紫题完全是在假(虽然我也跟风评了紫题),顶多黄题难度. 评黄题的主要原因是得知道约瑟夫递推公式,即fn = (fn - 1 +m) % n.表示n个人报数最后的获胜者,需要注意的是 ...
- thrift C++ Centos 安装
1.在官方下载thrift http://thrift.apache.org/download 这里下载thrift-0.11.0.tar.gz版本 2.如果想支持安装Cpp版本就需要先安装boost ...
- MyBatis框架(6)动态sql
本次全部学习内容:MyBatisLearning 什么是动态sql: mybatis的核心,对sql进行灵活的操作,通过对表达式的判断,对sql灵活的拼接 在之前小案例的基础上我们先进行简 ...
- 记录 iOS 各种跳转到系统应用
MARK ----拨打电话 NSString* phoneVersion = [[UIDevice currentDevice] systemVersion]; if (phoneVersion.fl ...
- 使用cmd命令创建vue(ivieiw)项目
条件,安装好nodejs 第一步:先使用 vue create 命令创建一个项目,等待创建完成. 1.切换目录 2.创建项目 vue create [项目名称] 第二步:切换到项目中. 第三步:使用 ...