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. DEV控件之ChartControl用法 z

    一.总体概述 这个控件包含3层,最外面的chartControl层.中间的XYDiagram层.最里面的Series层.功能非常强大,但同时使用起来也相对复杂,需要各个层之间相互协调设置才能达到自己想 ...

  2. sql with 写法

    with h_asign_id as ( select asign_id from assign_h h left join assignment a on a.id = h.asign_id whe ...

  3. Vim中增加ga键的vmap功能

    ga是Vim自带的显示光标字符编码的功能,但是反过来,没有从编码显示对应字符的功能. 因为编码是多位数,所以可视模式下写了此功能. 规则: 纯数字认为是10进制 其他情况都认为是16进制 纯数字的话, ...

  4. Android(java)学习笔记211:Android线程池形态

    1. 线程池简介  多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.     假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...

  5. isset() 与 array_key_exists() 比较

    1.对于数组值的判断不同,对于值为null或''或false,isset返回false,array_key_exists返回true: 2. 执行效率不同,isset是内建运算符,array_key_ ...

  6. [19/04/03-星期三] IO技术_其它流(RandomAccessFile 随机访问流,SequenceInputStream 合并流)

    一.RandomAccessFile 随机访问流 [版本1] /* *RandomAccessFile 所谓随机读取就是 指定位置开始或指定位置结束 的读取写入文件 * 实现文件的拆分与合并 模拟下载 ...

  7. 清除IE下input的叉叉

    很多时候,我们在开发过程中,设计师会在输入框后加上定制的清除图标,但是在IE下有IE自带的清除图标,肯定是不美观的. <style> ::-ms-clear, ::-ms-reveal{d ...

  8. Linux学习总结(十)-文件复制及查看, 环境变量

    一 文件复制及移动 1.命令 cp --------copy 的意思格式 cp 选项 源文件 目标文件a: 对于文件我们直接cp 文件 目标文件假定我们在普通用户家目录下/home/lv新建两个普通文 ...

  9. JavaScript小游戏--翻牌记忆游戏

    翻牌记忆游戏源码 1.有8张图片,每张图片要放两次,生成如下数组,长为16,[0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7] 其中两两相同的代表两张相同的图片,0对应文件夹image ...

  10. centos中java安装跟配置

    安装配置java环境 [root@JxateiLinux src]# Wget  http://download.oracle.com/otn-pub/java/jdk/8u161-b12/2f38c ...