英文:
What does UDPConn Close really do?
问题
如果UDP是一种无连接的协议,那么为什么UDPConn
有一个Close
方法?文档中说“Close关闭连接”,但UDP是无连接的。在UDPConn
对象上调用Close
方法是否是良好的实践?有什么好处吗?
http://golang.org/pkg/net/#UDPConn.Close
英文:
If UDP is a connectionless protocol, then why does UDPConn
have a Close
method? The documentation says "Close closes the connection", but UDP is connectionless. Is it good practice to call Close
on a UDPConn
object? Is there any benefit?
答案1
得分: 4
好的,以下是udpconn.Close
方法的代码:
func (c *conn) Close() error {
if !c.ok() {
return syscall.EINVAL
}
return c.fd.Close()
}
Close
方法关闭了c.fd
,那么c.fd
是什么呢?
type conn struct {
fd *netFD
}
ok
是一个netFD
网络文件描述符。让我们看一下Close
方法。
func (fd *netFD) Close() error {
fd.pd.Lock() // needed for both fd.incref(true) and pollDesc.Evict
if !fd.fdmu.IncrefAndClose() {
fd.pd.Unlock()
return errClosing
}
// Unblock any I/O. Once it all unblocks and returns,
// so that it cannot be referring to fd.sysfd anymore,
// the final decref will close fd.sysfd. This should happen
// fairly quickly, since all the I/O is non-blocking, and any
// attempts to block in the pollDesc will return errClosing.
doWakeup := fd.pd.Evict()
fd.pd.Unlock()
fd.decref()
if doWakeup {
fd.pd.Wakeup()
}
return nil
}
注意到了所有的decref
吗?
所以回答你的问题,是的,这是一个好的做法,否则网络文件描述符会在内存中悬空。
英文:
Good Question, let's see the code of udpconn.Close
http://golang.org/src/pkg/net/net.go?s=3725:3753#L124
func (c *conn) Close() error {
if !c.ok() {
return syscall.EINVAL
}
return c.fd.Close()
}
Closes c.fd
but what is c.fd ?
type conn struct {
fd *netFD
}
ok is a netFD
net File Descriptor. Let's look at the Close
method.
func (fd *netFD) Close() error {
fd.pd.Lock() // needed for both fd.incref(true) and pollDesc.Evict
if !fd.fdmu.IncrefAndClose() {
fd.pd.Unlock()
return errClosing
}
// Unblock any I/O. Once it all unblocks and returns,
// so that it cannot be referring to fd.sysfd anymore,
// the final decref will close fd.sysfd. This should happen
// fairly quickly, since all the I/O is non-blocking, and any
// attempts to block in the pollDesc will return errClosing.
doWakeup := fd.pd.Evict()
fd.pd.Unlock()
fd.decref()
if doWakeup {
fd.pd.Wakeup()
}
return nil
}
Notice all the decref
So to answer your question. Yes. Is good practice or you will leave hanging around in memory network file descriptors.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论