1、未初始化的channel读,阻塞

package main

import (
"fmt"
"time"
) func main() {
var ch chan int
go check(ch) fmt.Println("main runtime end")
time.Sleep(time.Second * 1000)
} func check(ch chan int) {
select {
case i := <-ch:
fmt.Println("read ch data=", i)
}
fmt.Println("check runtime exit")
}

2、未初始化的channel写,阻塞

package main

import (
"fmt"
"time"
) func main() {
go func() {
for {
time.Sleep(time.Second * 1)
}
}()
var ch chan int
go check(ch)
time.Sleep(time.Second * 1)
fmt.Println("xxxxxxx")
<-ch
fmt.Println("main runtime end")
time.Sleep(time.Second * 1000)
} func check(ch chan int) {
defer func() {
if r := recover(); r != nil {
fmt.Println("recover ", r)
}
}()
ch <- 1
fmt.Println("check runtime exit")
}

3、向已关闭的channel读,返回默认值和false

package main

import (
"fmt"
"time"
) func main() {
var ch chan int
ch = make(chan int)
go check(ch) fmt.Println("main runtime end")
close(ch)
time.Sleep(time.Second * 1000)
} func check(ch chan int) {
select {
case i, k := <-ch:
fmt.Println("read ch data=", i, " k=", k) //k=false i=0
}
fmt.Println("check runtime exit")
}

4、向已关闭的channel写,panic

package main

import (
"fmt"
"time"
) func main() {
var ch chan int
ch = make(chan int)
close(ch)
ch <- 1
fmt.Println("end")
time.Sleep(time.Second * 1000)
}

5、time.Timer Stop后,time.Timer.C将阻塞

package main

import (
"fmt"
"time"
) func main() {
tm := time.NewTimer(time.Second * 3)
go check(tm)
time.Sleep(time.Second * 1)
tm.Stop()
fmt.Println("main runtime end")
time.Sleep(time.Second * 1000)
} func check(tm *time.Timer) {
select {
case i, k := <-tm.C: //阻塞
fmt.Println("read ch data=", i, " k=", k)
}
fmt.Println("check runtime exit")
}

6、无缓冲与有缓冲channel的重要区别,无缓冲的channel在写时必须有读携程,否则会阻塞。如下例子,超时后向exit发数据会阻塞,因为只有一个携程,此时没有其他携程对exit进行读。【踩了坑才理解深刻】

package main

import (
"fmt"
"time"
) func main() {
exit := make(chan int)
go check(exit)
time.Sleep(time.Second * 100)
} func check(exit chan int) {
tm := time.NewTimer(time.Second * 3)
select {
case <-exit:
fmt.Println("exit")
case <-tm.C:
fmt.Println("time out")
exit <- 1
fmt.Println("exit <- 1 ok")
}
fmt.Println("check runtime exit")
}

例子2:

package main

import (
"fmt"
"time"
) func main() {
go func() {
for {
time.Sleep(time.Second * 1)
} }()
exit := make(chan int, 1)
exit <- 1
fmt.Println("end")
}

这里会直接END,如果exit:=make(chan int),会阻塞在exit<-1

最新文章

  1. Activity去Title的几种方式
  2. JQuery常用代码汇总
  3. 剖析javascript全局变量和局部变量
  4. Web Server 配置及上传文件
  5. python---sys
  6. [IIS]IIS扫盲(二)
  7. SQL中的连接查询及其优化原则
  8. LinkedList的实现原理
  9. C#Winfrom系统打印机调用/设置默认打印机
  10. SqlServer2008 之 应用积累
  11. python 中的列表解析和生成表达式 - 转
  12. ios怎样实现快速将显卡中数据读出压缩成视频在cocos2dx扩展开发中
  13. 第二章IPC——IPC与开启多进程
  14. VS 2017 Git failed with a fatal error的解决办法
  15. 早期MyBatis开发与接口式Mybatis开发的简介
  16. 解决ios微信页面回退不刷新的问题
  17. Apace Ignite剖析
  18. Docker的介绍及安装
  19. Spring整合quart初识
  20. Socket实例

热门文章

  1. leetcode Kth Largest Element in a Stream——要熟悉heapq使用
  2. 整合SpringDataJPA
  3. owin启动事项
  4. 第三篇 功能实现(1) (Android学习笔记)
  5. 延迟载入Dll(动态载入Dll)
  6. OJ_查找二叉树
  7. DevExpress WPF v18.2新版亮点(五)
  8. socket-重叠模型(overlap)
  9. 关于js中函数的调用问题
  10. 软件工程项目程序:WC