golang开发:channel使用
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使用的更多相关文章
- 用golang开发系统软件的一些细节
用golang开发系统软件的一些细节 作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 (本文的pdf版本) ...
- 使用golang 开发的 andriod应用
最近在捣鼓一个东东,就是使用golang开发andriod应用.说起来简单操作起来还挺麻烦,中间又学习了很多东西.比如ubuntu,docker,angular,ionic,jquery mobile ...
- golang开发android环境搭建_window
golang开发android环境搭建介绍 一 安装依赖软件: git:版本管理 go: go开发环境(版本>=1.5),可直接下载window版的go安装包. android studio: ...
- Windows下visual studio code搭建golang开发环境
Windows下visual studio code搭建golang开发环境 序幕 其实环境搭建没什么难的,但是遇到一些问题,主要是有些网站资源访问不了(如:golang.org),导致一些包无法安装 ...
- golang的Channel
golang的Channel Channel 是 golang 一个非常重要的概念,如果你是刚开始使用 golang 的开发者,你可能还没有真正接触这一概念,本篇我们将分析 golang 的Chann ...
- linux golang开发环境配置(离线方式)
<获取开发工具> 到https://www.golangtc.com/download 下载安装包, 根据自己的系统选择合适的开发包,这里选择go.1.9.2.linux-amd6 ...
- miniblink+golang开发windows gui应用
golang的优点自不必说了,这么好的语言怎么能缺少界面库呢?所以我使用miniblink开发了一个可以用html,css,js开发界面的浏览器,通过它你能为你的golang开发简单的界面.说白了其实 ...
- Linux下golang开发环境搭建
对于golang开发来说,Windows下可以用vscode或者liteide都不错,但是Linux下的开发也就只有vim了,所以怎么搞笑的利用vim进行golang开发呢? 参考官方推荐的一个插件: ...
- window / Linux 下 Golang 开发环境的配置
一直专注于使用python语言进行程序开发,但是却又一直被它的性能问题所困扰,直到遇到了天生支持高并发的Golang,这似乎也成了学习go语言最理所当然的理由.下面介绍下Go语言开发环境搭建的步骤: ...
随机推荐
- 牛客网PAT练兵场-统计同成绩学生
题解:开100的数组,进行存储人数,方便查询 题目地址:https://www.nowcoder.com/questionTerminal/3df4810cc0664b8bb848d785f68f7c ...
- vscode 安装go插件失败后,最简单的方法
vscode 安装go插件 参考: https://github.com/goproxy/goproxy.cn/blob/master/README.zh-CN.md https://goproxy. ...
- Nginx Ingress on TKE 部署最佳实践
概述 开源的 Ingress Controller 的实现使用量最大的莫过于 Nginx Ingress 了,功能强大且性能极高.Nginx Ingress 有多种部署方式,本文将介绍 Nginx I ...
- vue 里bus的使用
兄弟组件之间进行传值(非父子组件): 安装:npm install vue-bus 在main.js中引入vue-bus import Vue from 'vue'; import VueBus fr ...
- 深入理解SVM,软间隔与对偶问题
今天是机器学习专题的第33篇文章,我们继续来聊聊SVM模型. 在上一篇文章当中我们推到了SVM模型在线性可分的问题中的公式推导,我们最后得到的结论是一个带有不等式的二次项: \[\left\{\beg ...
- 【JAVA】给大家推荐一道有意思的java测试题。你知道答案吗?
作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985, QQ986945193 公众号:程序员小冰 public class Test { /** * * ...
- LoadRunner回放脚本遇到的问题(遇到就补上)
问题一:Error-26612:HTTP Status-code=500(Internal Server Error) 解决过程:google找到了关于这个错误有多种解决的方法,但是都不是我要的,最重 ...
- unity接入安卓SDK,与安卓相互通信
.接SDK是个什么样的活计? SDK的工作流程: 1. 从unity端出发,向安卓发起一系列的请求(unity call android). 2. 安卓端收到unity端调用,然后在具体调用SDK的一 ...
- springboot AOP实战
目录 AOP实战 maven依赖 定义切面 采用扫描类的方式 采用注解的方式 通知 前置通知 后置通知 返回通知 异常通知 环绕通知 JoinPoint 获取切点处的注解 git AOP实战 mave ...
- Tesseract OCR 安装尝试
1.简介 Tesseract是一个图像识别项目,将图中的文字识别出来.将一个.jpg .png 等等 的图片作为输入,.txt作为识别内容输出 Tesseract项目GitHub地址 2.安装 你可以 ...