golang channel 总结
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
golang channel 总结的更多相关文章
- golang channel的使用以及调度原理
golang channel的使用以及调度原理 为了并发的goroutines之间的通讯,golang使用了管道channel. 可以通过一个goroutines向channel发送数据,然后从另一个 ...
- golang channel关闭后,是否可以读取剩余的数据
golang channel关闭后,其中剩余的数据,是可以继续读取的. 请看下面的测试例子. 创建一个带有缓冲的channel,向channel中发送数据,然后关闭channel,最后,从channe ...
- golang channel原理
channel介绍 channel一个类型管道,通过它可以在goroutine之间发送和接收消息.它是Golang在语言层面提供的goroutine间的通信方式. 众所周知,Go依赖于称为CSP(Co ...
- golang channel 用法转的
一.Golang并发基础理论 Golang在并发设计方面参考了C.A.R Hoare的CSP,即Communicating Sequential Processes并发模型理论.但就像John Gra ...
- golang channel初次接触
goroutine之间的同步 goroutine是golang中在语言级别实现的轻量级线程,仅仅利用go就能立刻起一个新线程.多线程会引入线程之间的同步问题,经典的同步问题如生产者-消费者问题,在c, ...
- 如何优雅的关闭Golang Channel?
Channel关闭原则 不要在消费端关闭channel,不要在有多个并行的生产者时对channel执行关闭操作. 也就是说应该只在[唯一的或者最后唯一剩下]的生产者协程中关闭channel,来通知消费 ...
- golang channel几点总结
golang提倡使用通讯来共享数据,而不是通过共享数据来通讯.channel就是golang这种方式的体现. Channel 在golang中有两种channel:带缓存的和不带缓存. 带缓存的cha ...
- golang channel 源码剖析
channel 在 golang 中是一个非常重要的特性,它为我们提供了一个并发模型.对比锁,通过 chan 在多个 goroutine 之间完成数据交互,可以让代码更简洁.更容易实现.更不容易出错. ...
- golang channel本质——共享内存
channel是golang中很重要的概念,配合goroutine是golang能够方便实现并发编程的关键.channel其实就是传统语言的阻塞消息队列,可以用来做不同goroutine之间的消息传递 ...
- Golang channel 用法简介
channel 是 golang 里相当有趣的一个功能,大部分时候 channel 都是和 goroutine 一起配合使用.本文主要介绍 channel 的一些有趣的用法. 通道(channel), ...
随机推荐
- 【转】大型Vuex项目 ,使用module后, 如何调用其他模块的 属性值和方法
Vuex 允许我们把 store 分 module(模块).每一个模块包含各自的状态.mutation.action 和 getter. 那么问题来了, 模块化+命名空间之后, 数据都是相对独立的, ...
- IIS无法启动,应用程序池自动关闭
问题:打开网站中的资源,对应的应用程序池就自动停止 解决方案:在应用程序池上--右键--高级设置--进程模型--标识,更改了这项里的“内置账户”.将原有的“ApplicationPoolIdentit ...
- stund客户端使用结果说明
stun服务器是用于检测网络类型的重要工具. 源码地址:https://svwh.dl.sourceforge.net/project/stun/stun/0.97/stund-0.97.tgz 或者 ...
- js--阻止冒泡,捕获,默认行为
防止冒泡和捕获 w3c的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true· var el = window.document.getElementB ...
- gpu内存查看命令nvidia-smi
nvidia-smi nvidia-settings nvidia-xconfig
- java ArrayList 迭代器快速失败源码分析
先来看一个例子: @Test void test2() { ArrayList<String> list = new ArrayList<String>(); list.add ...
- 0-MAVEN SETTING
localRepository : 表示本地库的保存位置,也就是maven主要的jar包保存位置,默认在${user.dir}/.m2/repository,如果需要另外设置,就换成其他的路径 Ser ...
- 尚学堂java答案解析 第三章
本答案为本人个人编辑,仅供参考,如果读者发现,请私信本人或在下方评论,提醒本人修改 一.选择题 1.A 2.BD 解析:switch的的判断表达式的数据类型:byte short int ch ...
- day26-python操作redis二
字符串的操作 #redis中的string 在内存中都是按照一个key对应一个valus来存储的 import redis pool = redis.ConnectionPool(host=" ...
- JSONP解决跨域问题,什么是JSONP(转)
原文链接:https://www.cnblogs.com/xinxingyu/p/6075881.html 说到AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交换数据?第二个是跨域的 ...