go源码解析之TCP连接(五)——Close
Contents
go源码解析之TCP连接系列基于go源码1.16.5
连接关闭
上一章我们通过跟踪TCPConn的Write方法,了解了发送数据的过程以及fd的读写锁,本章将通过TCPConn的Close方法的跟踪来了解连接关闭的过程。
1. conn的Close方法
从上一章了解到TCPConn继承自conn,它的Close方法就是conn的Close,代码如下:
src/net/net.go
|
|
同样conn的Close调用了netFD的Close方法:
src/net/fd_posix.go
|
|
2. 回顾SetFinalizer
回顾一下SetFinalizer,它设置参数一被回收时需要执行的清理方法,Close这里将fd的清理方法删除,我们再回顾一下fd的清理方法是在什么时候被设置的:
src/net/fd_posix.go
|
|
src/net/fd_unix.go
|
|
可以看到在初始化netFD之后调用的setAddr方法中设置了清理方法。清理方法指定为netFD的Close。在Close方法中将清理方法删除,防止netFD被回收时重复执行Close。
3. poll.FD的Close方法
src/internal/poll/fd_unix.go
|
|
- increfAndClose方法将fd设置为关闭状态并唤醒其他所有等待锁的协程,在上一章有讲解。
- evict方法将阻塞等待io消息的协程唤醒,这块将在后续go语言实现io多路复用的章节详细讲解。
- decref与incref成对出现,如果fd的引用数量为0,将执行destory调用系统方法关闭fd
- runtime_Semacquire,如果fd是非阻塞模式,则需要请求信号量csema,等待destory方法完成并发送信号量后,再被唤醒
destory方法:
src/internal/poll/fd_unix.go
|
|
- CloseFunc进行系统调用关闭fd
- runtime_Semrelease释放信号量csema
4. 小结
关闭方法不会第一时间调用系统方法销毁系统fd,系统fd的销毁需要在不再有引用时执行。
Author 刘玮
LastMod 2022-02-12