延迟函数到底怎么实现呢?
- 每个
defer
语句都会形成一条deferproc
注册调用。 - 注册调用会把函数名称,函数参数,调用函数的宿主函数SP寄存器地址打包。
调用函数的宿主函数SP寄存器地址是什么?
func test(){
defer println("xxx")
}
func main(){
defer println(1)
defer println(2)
defer println(3)
test()
}
当我们打包println
语句的时候,实际上它会打包函数名称println
、参数1
、RSP的寄存器地址main.RSP
。这个打包会保存到哪呢?它实际上会存到当前goroutine的列表里G.deferlist
。一个goroutine代表完整一套调用逻辑。假设main.goroutine有三个defer,如果函数名称按照FIFO方式命名的话,main.goroutine的G.deferlist
包含的是main.println(1)
、main.println(2)
、main.println(3)
、test.println("xx")
。def