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 &lt;-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 &lt;-timer:
fmt.Println("time out")
break Loop
}
}

}

//获取管道chan1

func getChan() chan int {

return chan1

}

最新文章

  1. TYPESDK手游聚合SDK客户端远程开关:渠道支付黑名单
  2. android 实现返回键执行home键方法
  3. 3515 如何调试AT指令、查看拨号模块的打印
  4. Hive 按某列的部分排序 以及 删列操作
  5. Quartz.NET
  6. 夺命雷公狗-----React---2--组建
  7. 关于android初学者必须掌握的Activity的四大知识点
  8. jQuery时间轴插件:jQuery Timelinr
  9. HDU 4900 NO ACM NO LIFE(概率+枚举+搜索)(2014 Multi-University Training Contest 4)
  10. PC 端微信扫码注册和登录
  11. json2使用方法
  12. 解决WIN7上 SQL2008r2 由于防火墙问题 客户端无法远程连接的问题
  13. Nginx 在安装入门
  14. iOS开发UITableViewCell的选中时的颜色设置
  15. Kendo UI开发教程(24): 单页面应用(二) Router 类
  16. onConfigurationChanged方法的使用
  17. 使用控制台对Redis执行增删改查命令
  18. WebApi升级到2.0以后的XmlDocumentationProvider
  19. Win7上Spark WordCount运行过程及异常
  20. Codeforces Round #426 (Div. 2) C. The Meaningless Game

热门文章

  1. redis(以php代码为例)
  2. FPGA学习笔记(六)—— 时序逻辑电路设计
  3. mongodb shell 无法删除问题
  4. 【转】Java IO流 overview
  5. SPOJ ARCTAN
  6. 对付 MySQL 的死连接,Sleep的进程的来源探究[转]
  7. POJ 1064_Cable master
  8. Ubuntu 16.04设置rc.local开机启动命令/脚本的方法(通过update-rc.d管理Ubuntu开机启动程序/服务)
  9. Servlet的HelloWorld实例
  10. dtrace-conf 2016