在Golang中安全地关闭连接

11
当我打开一个套接字连接时,我会立即在套接字打开后的defer函数中放置socket.Close()逻辑。但是,如果socket.Close()导致另一个panic怎么办?我是否应该始终在外部defer中嵌套另一个defer/recover以防止程序崩溃?类似这样:http://play.golang.org/p/GnEMQS-0jj
谢谢, Elgs

2
根据我所知,socket.Close()不会引起panic。 - fuz
2
我不是完全确定:关闭(例如在net.TCPConn上)可能会导致错误,但我认为它不会引发panic。如果它引发panic,例如由于硬件损坏或内存不足,你的应用程序无论如何都会崩溃。根据你的情况,你可能想处理返回的错误,但在Close中处理panic似乎有点过度谨慎。 - Volker
@FUZxxl 当我试图关闭一个被服务器拒绝连接的客户端套接字时,它会出现 panic。有没有办法在不出现 panic 的情况下判断套接字是否可以安全关闭。或者我必须再嵌套一层 defer 来处理套接字关闭逻辑。 - user1663023
@ElgsQianChen 这似乎是Go语言中的一个bug,请在Go bugtracker上报告此问题。 - fuz
1个回答

11

通常情况下,您不需要过多担心panic。它们通常代表两类错误:开发人员错误(nil引用、数组越界)和系统级错误,您可能无法做太多关于这些错误(例如内存耗尽)。

正如其他人所说,socket.Close不会引起panic,而是返回一个错误。如果您这样做:

defer socket.Close()

这个错误被丢弃了,你不需要做任何其他的事情。

但是假设你确实想从恐慌中恢复。如果你的恢复处理程序是延迟执行的,那么你就不需要做任何其他的事情:

func main() {
  defer func() {
    if err := recover(); err != nil {
      fmt.Println(err)
    }
  }()
  defer panic("this will be recovered")
}

延迟函数是按相反顺序运行的:http://golang.org/ref/spec#Defer_statements

在包围函数返回之前,延迟函数会立即执行,按它们被延迟的相反顺序执行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接