defer底层原理
goroutine,解除阻塞,以使它去争取继续运行代码的机会。如此阻塞代码也是为了实现操作的互斥和元素值的完整。
扩展
- 发送操作和接收操作在什么时候可能会被长时间阻塞?
对于缓冲通道来说,如果通道已满,则对它的所有发送操作都将被阻塞,直到通道中有元素值被接收走,此时通道会通知阻塞队列的首个goroutine,通知顺序是公平的
相对的,如果通道已空,那么对它的所有接收操作会被阻塞,直到通道中有新的元素值出现。
对于非缓冲通道,无论是发送还是接收操作,一开始执行就会被阻塞,直到配对的操作也开始执行,才会继续。可以说非缓冲通道就是在用同步的方式传递数据。且用非缓冲通道时,数据并不会用通道作中转。
如果错误操作也会造成长时间阻塞,最典型的就是对值为nil(即未初始化)的通道进行操作。
- 发送操作和接收操作什么时候会引发panic?
对一个已经关闭的通道做发送操作会引发panic,但对已经关闭的通道可以进行接收操作
对一个已经关闭的通道进行关闭操作会引发panic。
defer底层原理
1、每次defer语句在执行的时候,都会将函数进行"压栈",函数参数会被拷贝下来。当外层函数退出时,defer函数会按照定义的顺序逆序执行。如果defer执行的函数为nil,那么会在最终调用函数中产生panic。
2、为什么defer要按照定义的顺序逆序执行
后面定义的函数可能会依赖前面的资源,所以要先执行。如果前面先执行,释放掉这个依赖,那后面的函数就找不到它的依赖了。
3、defer函数定义时,对外部变量的引用方式有两种
分别是函数参数以及作为闭包引用。
在作为函数参数的时候,在defer定义时就把值传递给defer,并被缓存起来。
如果是作为闭包引用,则会在defer真正调用的时候,根据整个上下文去确定当前的值。
4、defer后面的语句在执行的时候,函数调用的参数会被保存起来,也就是复制一份。
在真正执行的时候,实际上用到的是复制的变量,也就是说,如果这个变量是一个"值类型",那他就和定义的时候是一致的,如果是一个"引用",那么就可能和定义的时候的值不一致
defer配合recover
recover(异常捕获)可以让程序在引发panic的时候不会崩溃退出。
在引发panic的时候,panic会停掉当前正在执行的程序,但是,在这之前,它会有序的执行完当前goroutine的 defer列表中的语句。
全站分卷索引 · 29 卷
- 1代码随想录知识星球精华(最强八股文)第五版(Go篇))
- 2Go string 和 []byte 的区别
- 3数组和切片的区别
- 4扩容前后的Slice是一样的吗
- 5Go语言map是有序的还是无序的, 为什么
- 6go里面的map是并发安全的吗?如何并发安全
- 7Go 的错误处理和 Java 的异常处理对比
- 8介绍一下panic和recover
- 9什么是defer?有什么作用
- 10Go并发
- 11进程、线程的区别
- 12什么是go runtine
- 13Go语言中的Channel是什么, 有哪些用途,如何处理阻塞
- 14什么是互斥锁(mutex)?在什么情况下会用到它们?
- 15Mutex有几种模式
- 16goroutine什么情况会发生内存泄漏?如何避免。
- 17Go语言中GC的流程是什么
- 18Go 中的内存逃逸现象是什么?
- 19CAP 理论,为什么不能同时满足
- 20说一下 Gin 的路由怎么实现的
- 21简述slice的底层原理,和数组的区别是什么
- 22defer底层原理
- 23侵入式和非侵入式的区别
- 24goroutine与线程的区别
- 25goroutine在什么情况下会被挂起呢?
- 26GC(垃圾回收)原理 1.5版本
- 27简述Go的垃圾回收机制
- 28协程优势及其通信方式
- 29Go的内存对齐