返回信息流`go` + `chan` 配合使得`golang`具有独特的魅力,你会不自觉地用上多线程,甚至忘了自己正在使用多线程。但是,当你的程序结构复杂起来之后,那么各种坑也就出现了。
1 如果是非缓存chan,如果刚好赋值执行在取值之前,那么会Block,请确保`<-chan`不会被`chan<-`阻塞。
2 带缓存chan,赋值和取值是异步的,也就是传递的数值可能需要很久才被处理,甚至不会被处理,比如,`main`退出。请酌情选择缓存和非缓存`chan`,并在必要的地方使用`sync.WaitGroup`或返回值chan等方式确保下一步执行前数据已处理完成。
3 不管chan有无缓存,一定要考虑好赋值和取值的频次关系,如果不是一对一,那么一定要在某侧使用`select` + `default`,否则会block.
4 如果是长时间持续待命的程序,一定确保所有`go`启动的函数在完成任务时退出,否则,cpu和内存会爆炸。通知退出的方式,还是使用`chan`
5 以上这些,看起来不难,但如果`goroutine`数量上来,且彼此之间chan交叉,再加上实际生产环境总会有一些你没考虑到的异常,就不是很好保证了。
7 最后,能用`chan`实现互斥的地方还是推荐用`chan`,不要用`sync.Mutex`
这是一条镜像帖。来源:北邮人论坛 / golang / #488同步于 2016/7/20
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Golang机器人发帖
新手向--列举一些Go中chan使用容易犯的错
AzYet
2016/7/20镜像同步5 回复
订阅后,新回复会通过你的通知中心匿名送达。
5 条回复
~~gorouting~~ **goroutine** 多起来之后各种爽
【 在 AzYet 的大作中提到: 】
: [md]
: `go` + `chan` 配合使得`golang`具有独特的魅力,你会不自觉地用上多线程,甚至忘了自己正在使用多线程。但是,当你的程序结构复杂起来之后,那么各种坑也就出现了。
: 1 如果是非缓存chan,如果刚好赋值执行在取值之前,那么会Block,请确保`<-chan`不会被`chan<-`阻塞。
: ...................
标题不当,应该是新手容易遇到的误区,确实是特性不是语言的坑,但大意的话就会容易出现问题
【 在 jkfbrant 的大作中提到: 】
: 不知道楼主是什么场景,会觉得这些特性是问题。。。。。
之前也遇到一个坑。
stop := make(chan bool)
close(stop)的时候 <-stop会收到一条消息。
但是close并不会等另一个goroutine收到那个消息。所以:
goroutine1:
close(stop)
connection.close()
goroutine2:
select{
case msg := <- msgChan:
// use connection to send msg
case <-stop
return
}
这种代码,有可能在调用完close之后goroutine2还在执行发送消息的逻辑,然后报错。
【 在 AzYet 的大作中提到: 】
: [md]
: `go` + `chan` 配合使得`golang`具有独特的魅力,你会不自觉地用上多线程,甚至忘了自己正在使用多线程。但是,当你的程序结构复杂起来之后,那么各种坑也就出现了。
: 1 如果是非缓存chan,如果刚好赋值执行在取值之前,那么会Block,请确保`<-chan`不会被`chan<-`阻塞。
: ...................