golang中管道热替换
golang中管道替换问题
https://blog.csdn.net/cyk2396/article/details/78875347
1.运行以下代码:
var chan1 chan int
var chanLength int = 18
var interval time.Duration = 1500 * time.Millisecond
//var interval2 time.Duration = 1800 * time.Millisecond
//golang在替换通道时引起的问题
func main() {
chan1 = make(chan int, chanLength)
//该goroutine是每隔1.5秒向chan1中发送一个元素,
//当满足条件时,重置chan1,此时chan1会指向一个新通道
go func() {
for i := 0; i < chanLength; i++ {
if i > 0 && i%3 == 0 {
fmt.Println("chan1 reset")
chan1 = make(chan int, chanLength)
}
fmt.Println("send an value : ", i)
chan1 <- i
time.Sleep(interval)
}
fmt.Println("close chan1")
close(chan1)
}()
//用于接收chan1中的元素
receive(chan1)
}
func receive(chan2 chan int) {
fmt.Println("start receive value from chan1 ...")
timer := time.After(30 * time.Second)
Loop:
for {
select {
case e, ok := <-chan2:
if !ok {
fmt.Println("chan1 has closed ...")
break Loop
}
fmt.Println("receive value : ", e)
time.Sleep(interval)
case <-timer:
fmt.Println("time out")
break Loop
}
}
}
结果如下:
start receive value from chan1 ...
send an value : 0
receive value : 0
send an value : 1
receive value : 1
send an value : 2
receive value : 2
chan1 reset
send an value : 3
send an value : 4
send an value : 5
chan1 reset
send an value : 6
send an value : 7
send an value : 8
chan1 reset
send an value : 9
send an value : 10
send an value : 11
chan1 reset
send an value : 12
send an value : 13
send an value : 14
chan1 reset
send an value : 15
send an value : 16
send an value : 17
close chan1
time out
引起这个的原因是:对变量的重新赋值操作是无法被传递的。在上面这个demo中,当chan1指向了新管道时,receive()函数还是调用原来的旧管道。
解决办法是:通过函数调用每次都获取最新的管道。代码如下:
var chan1 chan int
var chanLength int = 18
var interval time.Duration = 1500 * time.Millisecond
var interval2 time.Duration = 1550 * time.Millisecond
//golang在替换通道时引起的问题
func main() {
chan1 = make(chan int, chanLength)
//该goroutine是每隔1.5秒向chan1中发送一个元素,
//当满足条件时,重置chan1,此时chan1会指向一个新通道
go func() {
for i := 0; i < chanLength; i++ {
if i > 0 && i%3 == 0 {
fmt.Println("chan1 reset")
chan1 = make(chan int, chanLength)
}
fmt.Println("send an value : ", i)
chan1 <- i
time.Sleep(interval)
}
fmt.Println("close chan1")
close(chan1)
}()
//用于接收chan1中的元素
receive()
}
func receive() {
fmt.Println("start receive value from chan1 ...")
timer := time.After(30 * time.Second)
Loop:
for {
select {
case e, ok := <-getChan(): //通过getChan()每次都获取最新的管道
if !ok {
fmt.Println("chan1 has closed ...")
break Loop
}
fmt.Println("receive value : ", e)
time.Sleep(interval2) // 时间间隔相比发送方的时间间隔增加50ms,为了在getChan()时能获取最新的chan
case <-timer:
fmt.Println("time out")
break Loop
}
}
}
//获取管道chan1
func getChan() chan int {
return chan1
}
最新文章
- TYPESDK手游聚合SDK客户端远程开关:渠道支付黑名单
- android 实现返回键执行home键方法
- 3515 如何调试AT指令、查看拨号模块的打印
- Hive 按某列的部分排序 以及 删列操作
- Quartz.NET
- 夺命雷公狗-----React---2--组建
- 关于android初学者必须掌握的Activity的四大知识点
- jQuery时间轴插件:jQuery Timelinr
- HDU 4900 NO ACM NO LIFE(概率+枚举+搜索)(2014 Multi-University Training Contest 4)
- PC 端微信扫码注册和登录
- json2使用方法
- 解决WIN7上 SQL2008r2 由于防火墙问题 客户端无法远程连接的问题
- Nginx 在安装入门
- iOS开发UITableViewCell的选中时的颜色设置
- Kendo UI开发教程(24): 单页面应用(二) Router 类
- onConfigurationChanged方法的使用
- 使用控制台对Redis执行增删改查命令
- WebApi升级到2.0以后的XmlDocumentationProvider
- Win7上Spark WordCount运行过程及异常
- Codeforces Round #426 (Div. 2) C. The Meaningless Game