浅析 Go 中的 defer channel close 的一些情况

栏目: Go · 发布时间: 6年前

内容简介:对于这个示例代码中的一些问题总结:一个可以让你停下来看一看,在茶歇之余给你帮助的小站,这里的内容主要是后端技术,个人管理,团队管理,以及其他个人杂想。

背景

defer func() {
		fmt.Println("defer start...")
		if err := recover(); err != nil {
			fmt.Printf("err1:%v\n", err)
		}
		fmt.Println("defer end...")
	}()
	c := make(chan int)
	// var c chan int
	go func() {
		// defer func() {
		// 	if err := recover(); err != nil {
		// 		fmt.Printf("err2:%v\n", err)
		// 	}
		// }()
		c <- 1
	}()
	// 以下两行代码对调的话,运行就正常了,否则会 panic
	close(c)
	fmt.Println(<-c)

	for i := 0; i < 100; i++ {
		cc, ok := <-c
		if ok {
			fmt.Println(cc)
		}
		// fmt.Println(<-c)
	}

对于这个示例代码中的一些问题总结:

  1. goroutine 里面的 panic ,在外面是不能被 recover() 的。
  2. chan 是阻塞式的。
  3. 从已关闭的 chan 读数据永远不会阻塞,一律返回空值。
  4. 向已关闭的 chan 以任何形式写数据都会 panic。
    • 如果我们先调用 go func() {c <- 1}() ,然后关闭 chan,此时再读取 chan 是有可能成功读取到数据,但是系统调度到执行 go func (即当我们向关闭的chan send 数据时,会报错 panic: send on closed channel)。
  5. defer 只针对当前协程有效。
    • 当主函数都执行完了,函数中的协程也没执行完,并且 chan 关闭,再在协程中写数据, recover() 是不会报错的,因为我主函数执行完都还没有执行到协程中 chan 写数据。
    • 当主函数未执行完就执行协程中的写数据,并且在写之前 chan 已经关闭,则会执行 defer,但是 recover() 没有捕捉到错误,因为错误发生在另外一个协程中。
  6. 关闭一个 nil channel 会发生 panic。

参考资料

  1. Close
  2. Why does Go panic on writing to a closed channel?
  3. Go 延迟函数 defer 详解

茶歇驿站

一个可以让你停下来看一看,在茶歇之余给你帮助的小站,这里的内容主要是后端技术,个人管理,团队管理,以及其他个人杂想。

浅析  <a href='https://www.codercto.com/topics/6127.html'>Go</a>  中的 defer channel close 的一些情况


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C语言程序设计

C语言程序设计

K. N. King / 吕秀锋、黄倩 / 人民邮电出版社 / 2010-4 / 79.00元

时至今日, C语言仍然是计算机领域的通用语言之一,但今天的 C语言已经和最初的时候大不相同了。本书最主要的一个目的就是通过一种“现代方法”来介绍 C语言,书中强调标准 C,强调软件工程,不再强调“手工优化”。这一版中紧密结合了 C99标准,并与 C89标准进行对照,补充了 C99中的最新特性。本书分为 C语言的基础特性、 C语言的高级特性、 C语言标准库和参考资料 4个部分。每章末尾都有一个“问与......一起来看看 《C语言程序设计》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

URL 编码/解码
URL 编码/解码

URL 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试