channel主要是用于多个goroutine之间通信

channel语法

channel是引用类型,需要实用make来创建channel,如下

make(chan Type, [buffer])

chan Type 通道的类型

buffer 是可选参数,代表通道缓冲区的大小(省略则代表无缓冲)

向channel里面写入数据使用 <- 符号

q := make(chan bool)
q<-true

从channel里面读取数据也是使用 <- 符号,只不过写入的channel在右边,读取的时候channel在左边。意思跟方向是一致的,一个是数据进入channel,一个是数据从channel出去

q := make(chan bool)
<-q

有缓冲channel的使用

我们一直使用的无缓冲的channel,今天主要学习下有缓存的channel。

无缓冲的channel,写入数据后一定要有goroutine 从channel读取数据后再写入,否则程序会panic。

func main() {
ch := make(chan int)
ch<-1
} fatal error: all goroutines are asleep - deadlock! goroutine 1 [chan send]:

有缓冲的channel,可以写入缓冲大小个数据,可以没有goroutine从channel读取。

func main() {
ch := make(chan int,2)
ch<-1
ch<-2
} Process finished with exit code 0

执行结果跟预期是一致的。

有缓冲大小的channel使用场景

假如我们有一个任务需要10个goroutine去调度执行,只要有一个goroutine执行完毕,调度就应该结束。我们看下伪代码

func test(wg *sync.WaitGroup,ch chan int,i int) {
fmt.Println("test code")
ch<-i
} func main() {
fmt.Println("start",runtime.NumGoroutine())
ch := make(chan int)
wg := new(sync.WaitGroup)
for i:=0;i<10;i++ {
wg.Add(1)
go test(wg,ch,i)
}
fmt.Println(<-ch)
fmt.Println("end",runtime.NumGoroutine())
wg.Done()
} start 1
test code
9
end 10

从执行结果上看,是第9个goroutine首先执行完毕了。程序也正常退出了。但是我们看到,加上主goroutine,内存中一共有11个goroutine,程序退出的时候还有10个goroutine,减去一个主goroutine,还有9个goroutine没有退出,这个对程序来说是不允许,可能会泄漏或者长期占用资源不释放。

但是我们如果使用了有缓冲的channel,就可以利用channel的缓冲机制正常退出全部的goroutine了。

看下代码

func test(wg *sync.WaitGroup,ch chan int,i int) {
ch<-i
} func main() {
fmt.Println("start",runtime.NumGoroutine())
ch := make(chan int, 10)
wg := new(sync.WaitGroup)
for i:=0;i<10;i++ {
wg.Add(1)
go test(wg,ch,i)
}
fmt.Println(<-ch,"success")
for i:= 0;i<9;i++ {
fmt.Println(<-ch)
}
fmt.Println("end",runtime.NumGoroutine())
wg.Done()
} start 1
0 success
1
2
4
3
5
6
7
8
9
end 1 Process finished with exit code 0

打印success的时候,第一个goroutine已经将任务完成,循环9次将channel里面的数据读取出来,保证创建的goroutine都不会阻塞能够正常退出来。

golang开发:channel使用的更多相关文章

  1. 用golang开发系统软件的一些细节

    用golang开发系统软件的一些细节 作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 (本文的pdf版本) ...

  2. 使用golang 开发的 andriod应用

    最近在捣鼓一个东东,就是使用golang开发andriod应用.说起来简单操作起来还挺麻烦,中间又学习了很多东西.比如ubuntu,docker,angular,ionic,jquery mobile ...

  3. golang开发android环境搭建_window

    golang开发android环境搭建介绍 一 安装依赖软件: git:版本管理 go:  go开发环境(版本>=1.5),可直接下载window版的go安装包. android studio: ...

  4. Windows下visual studio code搭建golang开发环境

    Windows下visual studio code搭建golang开发环境 序幕 其实环境搭建没什么难的,但是遇到一些问题,主要是有些网站资源访问不了(如:golang.org),导致一些包无法安装 ...

  5. golang的Channel

    golang的Channel Channel 是 golang 一个非常重要的概念,如果你是刚开始使用 golang 的开发者,你可能还没有真正接触这一概念,本篇我们将分析 golang 的Chann ...

  6. linux golang开发环境配置(离线方式)

    <获取开发工具>     到https://www.golangtc.com/download 下载安装包, 根据自己的系统选择合适的开发包,这里选择go.1.9.2.linux-amd6 ...

  7. miniblink+golang开发windows gui应用

    golang的优点自不必说了,这么好的语言怎么能缺少界面库呢?所以我使用miniblink开发了一个可以用html,css,js开发界面的浏览器,通过它你能为你的golang开发简单的界面.说白了其实 ...

  8. Linux下golang开发环境搭建

    对于golang开发来说,Windows下可以用vscode或者liteide都不错,但是Linux下的开发也就只有vim了,所以怎么搞笑的利用vim进行golang开发呢? 参考官方推荐的一个插件: ...

  9. window / Linux 下 Golang 开发环境的配置

    一直专注于使用python语言进行程序开发,但是却又一直被它的性能问题所困扰,直到遇到了天生支持高并发的Golang,这似乎也成了学习go语言最理所当然的理由.下面介绍下Go语言开发环境搭建的步骤: ...

随机推荐

  1. Shell编程—sed和gawk

    1文本处理 1.1sed 编辑器 sed编辑器被称作流编辑器(stream editor),和普通的交互式文本编辑器恰好相反.在交互式文本编辑器中(比如vim),你可以用键盘命令来交互式地插入.删除或 ...

  2. wordpress个人常用标签调用

    wordpress常见标签调用,老是容易忘记,又要找半天,干脆搬到网站上. <?php bloginfo('name');?>网站名称 url <?php echo home_url ...

  3. springBoot整合spring security实现权限管理(单体应用版)--筑基初期

    写在前面 在前面的学习当中,我们对spring security有了一个小小的认识,接下来我们整合目前的主流框架springBoot,实现权限的管理. 在这之前,假定你已经了解了基于资源的权限管理模型 ...

  4. 这应该是最适合国内用户的K3s HA方案

    前 言 在面向生产环境的实践中,高可用是我们无法避免的问题,K3s本身也历经多个版本的迭代,HA方案也进行了不断优化,形成了目前的比较稳定的HA方案. 目前官方提供两种HA方案: 嵌入式DB的高可用( ...

  5. HDU - 1005 -Number Sequence(矩阵快速幂系数变式)

    A number sequence is defined as follows:  f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) m ...

  6. webpack 多页面构建

    目标: 基于webpack支持react多页面构建(不用gulp,gulp-webpack 构建速度太慢[3]), generator-react-webpack 对单页面支持很好,但对多页面,需要改 ...

  7. Mybatis参数传递及返回类型

    mybatis参数传递: 单个参数:不做特殊处理        #{参数名}:取出参数值    多个参数:做特殊处理        多个参数会被封装成一个map            key:para ...

  8. input.nextLine()和input.next()的区别

    输入:dfjjvh eigdj iugydchdgh 使用input.next()读取到的是:dfjjvh 使用input.nextLine()会读取全部

  9. idea报错cannot resolve symbol servlet

    解决方法:在project structure中导入包.该包在tomcat安装目录的lib文件夹.导入之后点击Apply.

  10. 【Oracle/Sql】清除重复而带出的性能问题

    笔者使用的环境: # 类别 版本 1 操作系统 Win10 2 数据库 Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bi ...