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的更多相关文章

  1. 如何理解golang中的nil

    nil的奇怪行为 刚接触golang时,发现nil在不同的上下文,行为表现是不同的,并且和其他语言中的表现,也不大相同 实例1:输入true, true, false,不符合传递性 func main ...

  2. [Go] 理解 golang 中的 nil

    nil是什么 相信写过Golang的程序员对下面一段代码是非常非常熟悉的了: if err != nil { // do something.... } 当出现不等于nil的时候,说明出现某些错误了, ...

  3. golang中的channel

    1. 概念 单纯的将函数并发执行是没有意义的,函数与函数之间需要交换数据才能提现并发执行函数的意义虽然可以使用共享内存来进行数据的交换,但是在共享内存在不同的goroutine中容易发生竟态问题,为了 ...

  4. 理解golang中的function types

    先找个例子来看一下: package main import "fmt" // Greeting function types type Greeting func(name st ...

  5. golang中并发sync和channel

    golang中实现并发非常简单,只需在需要并发的函数前面添加关键字"go",但是如何处理go并发机制中不同goroutine之间的同步与通信,golang 中提供了sync包和channel ...

  6. golang中并发的相关知识

    golang中done channel理解:https://segmentfault.com/a/1190000006261218 golang并发模型之使用Context:https://segme ...

  7. go---weichart个人对Golang中并发理解

    个人觉得goroutine是Go并行设计的核心,goroutine是协程,但比线程占用更少.golang对并发的处理采用了协程的技术.golang的goroutine就是协程的实现. 十几个gorou ...

  8. golang 中 channel 的非阻塞访问方法

    在golang中,基本的channel读写操作都是阻塞的,如果你想要非阻塞的,可以使用如下示例: 即只要在select中加入default,阻塞立即变成非阻塞: package main import ...

  9. 进一步认识golang中的并发

    如果你成天与编程为伍,那么并发这个名词对你而言一定特别耳熟.需要并发的场景太多了,例如一个聊天程序,如果你想让这个聊天程序能够同时接收信息和发送信息,就一定会用到并发,无论那是什么样的并发. 并发的意 ...

随机推荐

  1. 小技巧:Mac下Metasploit渗透Oracle环境的搭建

    Metasploit是一款开源的安全漏洞检测工具,可以帮助安全和IT专业人士识别安全性问题,验证漏洞的缓解措施,并管理专家驱动的安全性进行评估,提供真正的安全风险情报.这些功能包括智能开发,密码审计, ...

  2. request.getParameterMap和request.getParameter不一样的显示

    public class KeywordUtil {    /**     * 只提q参数关键字     *     * @param request     * @return 处理后的关键字Str ...

  3. 十一.安装Redis

    redis是一个NOSql数据库,在java web中,经常用来存储session等,官网是https://redis.io/ 当前官网指出的稳定版本为3.2.6,下载地址为http://downlo ...

  4. 二·安装Subversion(基于Centos7)

    1.在网站http://archive.apache.org/dist/subversion/中下载对应的版本,我的操作系统是centos, 所以我下载了Linux generic版本subversi ...

  5. ADF系列-1.EO的各个属性初探

    ADF中的EO可以看做关系型数据库中表的java展现形式. 1.Type 此处的Type是java的类型,而需要映射的是数据库的类型,两者之间存在一些差异,各个映射关系如下: 数据库列类型 BC 属性 ...

  6. 【[POI2015]WIL-Wilcze doły】

    第一篇题解确实会被讨论区里的数据hack掉,那么就随便水一个不会被hack掉的题解吧 首先我们尝试着发现这道题的一些结论,你就会发现答案是单调的不降的 这里的答案不降指的是选择每一个位置\(i\)作为 ...

  7. xampp安装及使用时的问题总结

    本文主要介绍易错点,具体安装过程可参考链接1 1.首先要以管理员身份运行,否则报错. 2.如果你的网站首页名字不是index,那么你在访问的时候就必须输入你首页的全称. 3.htdocs就是网站的根目 ...

  8. BootstrapTable返回结果集递增序号

    { 'field': '', 'title': '序号', 'align': 'center', 'width': '5%', 'formatter': function (value, row, i ...

  9. $.ajax方法success方法窗口弹不出

  10. vue使用iview Timeline 时间轴不显示问题

    vue Timeline 时间轴不显示渲染的效果 官网代码 <Timeline pending> <TimelineItem>发布1.0版本</TimelineItem& ...