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语言开发环境搭建的步骤: ...
随机推荐
- Newbe.Claptrap 框架入门,第三步 —— 定义 Claptrap,管理商品库存
接上一篇 Newbe.Claptrap 框架入门,第二步 —— 简单业务,清空购物车 ,我们继续要了解一下如何使用 Newbe.Claptrap 框架开发业务.通过本篇阅读,您便可以开始学会添加一个全 ...
- 问卷星导入数据到SPSS,数据变成-3是什么原因?
问卷星将数字“-3”表示为筛选或者跳转题:如果问卷中有设计筛选或者跳转,此时则会出现“-3”这个数字. 解决办法1 分析时首先进行筛选,然后再分析,便不会出现“-3”,而且一定需要这样进行.“筛选样本 ...
- 区块链入门到实战(30)之Solidity – 基础语法
一个 Solidity 源文件可以包含任意数量的合约定义.import指令和pragma指令. 让我们从一个简单的 Solidity 源程序开始.下面是一个 Solidity 源文件的例子: prag ...
- [ASP.NET Core开发实战]基础篇04 主机
主机定义 主机是封闭应用资源的对象. 设置主机 主机通常由 Program 类中的代码配置.生成和运行. HTTP项目(ASP.NET Core项目)创建泛型主机: public class Prog ...
- manualresetevent的用法学习
ManualResetEvent 允许线程通过发信号互相通信. 通常,此通信涉及一个线程在其他线程进行之前必须完成的任务. 当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时,它调用 Re ...
- Mac本地生成SSHKey的方法
1. 查看秘钥是否存在 打开终端查看是否已经存在SSH密钥:cd ~/.ssh 如果没有密钥则不会有此文件夹,有则备份删除, 也可以直接删除, 2.生成新的秘钥, 命令如下 $ssh-keygen ...
- Unity动态绑定按钮触发方法
在使用unity制作UI的过程中,基本都需要接触到按钮,然后按钮要起作用的话,那么就需要为按钮绑定响应方法. 为按钮绑定触发的方法,我知道的有两种方法,第一种:手动使用unityEditor 绑定,另 ...
- HDU-4417-Super Mario(主席树解法)
Mario is world-famous plumber. His “burly” figure and amazing jumping ability reminded in our memory ...
- 原生js实现jquery的siblings()
Element.prototype.siblings = function(callback){ var siblingElement = []; var parentAllElement = []; ...
- 【微信小程序】常用组件及自定义组件
(一) 常用标签 组件你可以理解为传统页面开发时候的各种标签,例如 div span 等等,我这里只说一些常用的,这样就能能搭建出一个基本的页面了,但是如果想要更加美观以及拥有更好的体验,就需要 XS ...