channel的基本使用
1、管道分类
- 读写管道
- 只读管道
- 只写管道
- 缓冲通道 :创建时指定大小(如果不指定默认为非缓冲通道)
2、正确使用管道
管道关闭后自能读,不能写
写入管道不能超过管道的容量cap,满容量还写则会阻塞
管道为空时,如果没有关闭,则继续读取会阻塞当前线程,直到有东西写入管道
m,ok:=<-intChan //ok用来检测产是否已经关闭 false代表关闭了,关闭了m就是默认值
一般如下操作才可以判断读取是否完毕,如果写进程没有关闭管道则说明还有东西要写
v,ok:=<-intChan
if !ok{
fmt.Println("读取完毕")
break
}
3、管道遍历与访问
- for-range访问
- select访问(常用)
for-range
//gor-range 如果管道没有数据同时还没有关闭 则会一直阻塞等待
go func() {
for i:=range c{ //注意这里没有ok判断是否关闭了 只有一个返回值
fmt.Println(i)
}
}()
下面这种情况for-range会阻塞,1秒后打印1,和 “关闭了”,如果没写同时又没有关闭,那么则会一直阻塞
ch := make(chan int)
go func() {
time.Sleep(time.Second)
//close(ch)
ch<-1
}()
go func() {
for i:=range ch{
log.Println(i)
}
log.Println("关闭了")
}()
time.Sleep(time.Hour)
下面的这种情况,for-range在一秒后会结束 ,同时打印“关闭了”
ch := make(chan int)
go func() {
time.Sleep(time.Second)
close(ch)
//ch<-1
}()
go func() {
for i:=range ch{
log.Println(i)
}
log.Println("关闭了")
}()
time.Sleep(time.Hour)
select
select会随机选择case里面没有阻塞的管道进行读取或写入,如果都阻塞则执行default语句,一般select都会伴随一个default语句
c:=make(chan string,2)
send:= func(v string) {
select {
case c<-v:log.Println("输入",v)
default:log.Println("缓冲区已经满")
}
}
receive:= func() string {
select {
case v:=<-c:return v
default:
log.Println("缓冲区空")
return ""
}
}
send("h1")
send("h2")
send("h3") //输入失败
log.Println(receive())
log.Println(receive())
log.Println(receive()) //取失败
当管道关闭时,select也会执行成功,如下打印了一秒‘等' 之后就会结束,这里没有往管道写东西,所以结束时打印的是默认值0
ch := make(chan int)
//go func() {
// ch <- 1
//}()
go func() {
time.Sleep(time.Second)
close(ch)
}()
go func() {
for {
time.Sleep(time.Microsecond*500)
select {
case v := <-ch:
log.Println(v)
return
default:
log.Println("等")
}
}
}()
time.Sleep(time.Hour)
4、阻塞情况
1、没有关闭,同时管道元素为0,读进程阻塞
2、没有关闭,同时管道元素已经满,则写进程阻塞,无缓冲管道的话则会阻塞在写,直到有人读
3、关闭管道,读光了还读,则读取出来的是对应类型管道的默认空值,在一个关闭通道进行写操作会报错
ch:=make(chan int,1)
ch<-1
close(ch)
log.Println(<-ch) //1
log.Println(<-ch) //0
log.Println(<-ch)//0
a,ok:=<-ch
log.Println(a,ok)//0 false
关闭管道,还写,则报错
无缓冲=堵塞,缓冲=非堵塞 无缓冲是同步,有缓冲是异步
像下面这个无缓冲管道,没人读则一直阻塞,只会打印A1,有一个管道读走了才会继续执行写操作,就比如快递员来发快递,只会等你拿走快递才会离开,否则一直在等你来拿
ch := make(chan int)
go func() {
for{
log.Println("A1")
time.Sleep(time.Second)
//close(ch)
ch<-1
log.Println("A2")
}
}()
那如果我把cap设置成1呢?
ch := make(chan int,1)
go func() {
for{
log.Println("A1")
time.Sleep(time.Second)
//close(ch)
ch<-1
log.Println("A2")
}
}()
打印如下,可以写一个
2020/03/21 20:02:59 A1
2020/03/21 20:03:00 A2
2020/03/21 20:03:00 A1
其他关于通道的使用可以看这两篇博客
go通道的常见使用场景.
go通道的优雅关闭.
channel的基本使用的更多相关文章
- Golang, 以17个简短代码片段,切底弄懂 channel 基础
(原创出处为本博客:http://www.cnblogs.com/linguanh/) 前序: 因为打算自己搞个基于Golang的IM服务器,所以复习了下之前一直没怎么使用的协程.管道等高并发编程知识 ...
- TODO:Go语言goroutine和channel使用
TODO:Go语言goroutine和channel使用 goroutine是Go语言中的轻量级线程实现,由Go语言运行时(runtime)管理.使用的时候在函数前面加"go"这个 ...
- GO语言之channel
前言: 初识go语言不到半年,我是一次偶然的机会认识了golang这门语言,看到他简洁的语法风格和强大的语言特性,瞬间有了学习他的兴趣.我是很看好go这样的语言的,一方面因为他有谷歌主推,另一方面他确 ...
- Critical: Update Your Windows Secure Channel (cve-2014-6321,MS14-066)
前言:风雨欲来山满楼,下半年开始各种凶猛的漏洞层出不穷,天下已经不太平,互联网已经进入一个新的台阶 0x01 cve-2014-6321 11月的补丁月,微软请windows的用户吃了顿大餐,发布了1 ...
- JAVA NIO Channel
Basic: 多数通道都是链接到开发的文件描述符的.Channel类提供维持平台独立性的抽象过程. 通道是一种途径,访问和操作操作系统,缓冲区是数据操作点: Channel类继承结构图: 通过 ...
- channel Golang
Golang, 以17个简短代码片段,切底弄懂 channel 基础 (原创出处为本博客:http://www.cnblogs.com/linguanh/) 前序: 因为打算自己搞个基于Golang的 ...
- go channel
channel 是go语言中不同goroutine之间通信一种方法 //定义一个channel c := make(chan bool) //向channel中写入 c <- true //读取 ...
- [bigdata] flume file channel CPU消耗比 memory channel高的原因
https://www.quora.com/Why-does-flume-take-more-resource-CPU-when-file-channel-is-used-compared-to-wh ...
- 图解Netty之Pipeline、channel、Context之间的数据流向。
声明:本文为原创博文,禁止转载. 以下所绘制图形均基于Netty4.0.28版本. 一.connect(outbound类型事件) 当用户调用channel的connect时,会发起一个 ...
- go:channel(未完)
注:1)以下的所有讨论建立在包含整形元素的通道类型之上,即 chan int 2)对于“<-”我的理解是,它可能是一个操作符(接收操作符),也 可能是类型的一部分(如“chan<- in ...
随机推荐
- 用 20 行 python 代码实现人脸识别!
点击上方"Python编程与实战",选择"置顶公众号" 第一时间获取 Python 技术干货! 阅读文本大概需要 11分钟. 今天给大家介绍一个世界上最简洁的人 ...
- 查漏补缺:QT入门
1.什么世QT Qt是一个跨平台的C++图形用户界面应用程序框架,为应用程序开发者提供建立艺术级图形界面所需的所有功能.它是完全面向对象的,容易扩展,并且允许真正的组建编程. 2.支持平台 Windo ...
- 算法拾遗[4]——STL用法
主要bb一下优先队列和字符串吧. 哦还有 bitset. 优先队列 定义很容易: priority_queue<int> pq; 内部是一个堆. 基本操作 pq.top() 取堆顶元素; ...
- vagrant 虚拟机配置最佳实践
Mac VirtualBox Vagrant 管理虚拟机 这篇文章定位是在理解了 vagrant 相关概念之后,教你如何灵活玩转自己的虚拟机配置 本文为 @favoorr 常用的 Mac Virtua ...
- IDEA系列(九)Intellij IDEA界面介绍 - 哲也的博客
原文出处:https://github.com/judasn/IntelliJ-IDEA-Tutorial 首次打开 重点说明: IntelliJ IDEA 是没有类似 Eclipse 的工作空间的概 ...
- 在博客中显示图片_Mac版
主要是防止自己忘掉 为了解决一开始自己想在写入的博客中添加本地图片,直接链接的话在自己的电脑倒是可以显示图片,但是在别人的电脑上就没办法加载图片了,问各路大神也没人愿意解答,百度也没有想要的答案,只好 ...
- Microsoft Translator:消除面对面交流的语言障碍
Translator:消除面对面交流的语言障碍" title="Microsoft Translator:消除面对面交流的语言障碍"> James Simm ...
- Animate.css动画库,简单的使用,以及源码剖析
animate.css是什么?能做些什么? animate.css是一个css动画库,使用它可以很方便的快捷的实现,我们想要的动画效果,而省去了操作js的麻烦.同时呢,它也是一个开源的库,在GitHu ...
- Visual studio2019配置OPENCV 时属性管理器中没有Microsoft.Cpp.x64.user的解决办法
方法一:重新下载Visual studio2017,再次打开2019就会出现Microsoft.Cpp.x64.user,感觉有些麻烦,也占电脑空间,推荐方法二. 方法二:与方法一原理相同,下载201 ...
- 从头认识js-基本概念(关键字,保留字,数据类型)
语法 ECMAScript的语法大量借鉴了C及其他类C语言(如Java和Perl)的语法.因此,熟悉这些语言的开发人员在接受ECMSAScript更加宽松的语法时,一定会有一种轻松自在的感觉. 区分大 ...