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. QT容器map的插入,修改,遍历

    除了map,QT的容器还有hash,以及迭代器等,这里写的是map #include "mainwindow.h" #include <QApplication> #i ...

  2. Yii2用Gii自动生成Module+Model+CRUD

    1. 开启gii模块 common/config/main-local.php加入下面代码 return [ 'modules' => [ 'gii' => [ 'class' => ...

  3. mem系函数总结

    memset(); 原型: void *memset(void *s, int ch, size_t n); 含义:   将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值,块的 ...

  4. .NET事务

    概述 事务ACID特性 事务将一系列的工作视为一个工作单元,它具有 ACID 特性: A:Atomicity 不可分性也就是说事务中有多项工作,如果有一项工作失败了,整个事务就算失败了. C:Cons ...

  5. Oracle练习详解

    --1.查询emp表,显示薪水大于2000,且工作类别是MANAGER的雇员信息 select * from emp where sal > 2000and job = 'MANAGER'; - ...

  6. bootstrap table footerFormatter用法 统计列求和 sum、average等

    其实上一篇blog里已经贴了代码,简单解释一下吧: 1.showFooter: true,很重要,设置footer显示: $(cur_table).bootstrapTable({ url: '/et ...

  7. 我上线的android版app

    把自己开发的几个小的app上线了,在自己的博客中推广一下吧: 聊天兔子: 下载地址:http://android.myapp.com/myapp/detail.htm?apkName=com.fuly ...

  8. django.db中的transaction

    transaction.set_autocommit(0) ..... ........ ................ transaction.commit() 可以使夹在其两句中间的所有SQL语 ...

  9. Yii 不完全解决方案(一)

    此文意在记录 Yii 开发过程中的小问题解决方案 1. Yii 中 Js 和 Css 文件的引入. 我们就从最简单的问题开始吧,说起来也不是问题,只是语法罢了.假设我们的 js 文件都放在和 prot ...

  10. sort论文和代码解读

    流程:1.detections和trackers用匈牙利算法进行匹配 2.把匹配中iou < 0.3的过滤成没匹配上的(1.2步共同返回匹配上的,没匹配上的trackers,没匹配上的detec ...