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 ...
随机推荐
- Twitter类社交平台 用比例建立新的“好坏”与社会焦点
用比例建立新的"好坏"与社会焦点" title="Twitter类社交平台 用比例建立新的"好坏"与社会焦点"> 互联网全面 ...
- 我在linux的第一个C程序
今天在虚拟机装起了linux,根据大家学习所需要,可以安装自己喜欢的版本,我这里装的是centos 7.0版本,也正是学习的开始,现在来看看简洁大气的centos界面吧: 在centos编译C ...
- 谷歌Waymo估值700亿:自动驾驶迎来春天,但前路漫漫
在经过近一年的法庭之争后,Waymo与Uber的自动驾驶专利权诉讼案于近日宣布和解.最终的结果,是Uber向Waymo支付0.34%股权(目前价值2.44亿美元).但事实上,与Uber的官司解决后,一 ...
- 添砖加瓦:几种常见的数据摘要算法(MD5、CRC32、SHA1和SHA256)
1.算法概述 数据摘要算法是密码学算法中非常重要的一个分支,它通过对所有数据提取指纹信息以实现数据签名.数据完整性校验等功能,由于其不可逆性,有时候会被用做敏感信息的加密.数据摘要算法也被称为哈希(H ...
- Leetcode 063 不同路径二
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为"Start" ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在下图中标记为" ...
- 6. Go 语言中结构体的使用
1. 结构体的定义格式 在go语言中结果的定义格式如下: 123 type structName struct { filedList} 列子如下: 1234 type Person struct { ...
- 基于物理的渲染——间接光照
在前面的文章中我们已经给出了基于物理的渲染方程: 并介绍了直接光照的实现.然而在自然界中,一个物体不会单独存在,光源会照射到其他的物体上,反射的光会有一部分反射到物体上.为了模拟这种环境光照的形式,我 ...
- Android空包签名
空包签名 搜狗.优亿等Android市场,上传应用需要提供一个与要上传的应用相同签名的空包.这个空包是相应官方市场提供的,下载好之后需要使用命令行进行签名.具命令如下: 1 jarsigner -ve ...
- 如何正确的hook方法objc_msgSend · jmpews
如何正确的hook方法objc_msgSend 前言 如果希望对 Objective-C 的方法调用进行 log, 一个很好的解决方法就是 hook 方法 objc_msgSend, 当然想到的就是利 ...
- Jenkins+Git+Fastlane+Fir CI集成
上一篇有讲关于fastlane自动化部署,本篇将会着重讲关于fastlane的实际应用. 目标: 利用自动化jenkins打包工具,自动拉取git仓库代码 不需要通过手动检查修改xcode中项目配置修 ...