Golang 中的安全关闭连接

Posted

技术标签:

【中文标题】Golang 中的安全关闭连接【英文标题】:Safe close connection in Golang 【发布时间】:2013-12-28 01:06:14 【问题描述】:

当我打开一个套接字连接时,我在打开套接字后立即将 socket.Close() 逻辑放在一个 defer 函数中。但是,如果 socket.Close() 会引起另一个恐慌怎么办?我是否应该总是在外部延迟中嵌套另一个延迟/恢复以防止我的程序崩溃?像这样:http://play.golang.org/p/GnEMQS-0jj

谢谢, 埃尔格斯

【问题讨论】:

socket.Close() 不会引起恐慌 IIRC。 我不太确定:关闭(例如在 net.TCPConn 上)可能会导致错误,但我认为它不会恐慌。如果它恐慌,例如由于硬件损坏或内存不足,您的应用程序无论如何都会被炸毁。根据您的情况,您可能想要处理返回的错误,但在 Close 中处理恐慌似乎有点偏执。 @FUZxxl 当我尝试关闭服务器拒绝连接的客户端套接字时,它会发生恐慌。有什么方法可以判断套接字是否可以安全关闭而不会惊慌。还是我必须为套接字关闭逻辑再嵌套一层延迟。 @ElgsQianChen 这看起来像 Go 中的一个错误。请在Go bugtracker 报告错误。 【参考方案1】:

通常您不必担心恐慌。它们通常代表两类错误:开发人员错误(无引用、数组越界)和您可能无能为力的系统级错误(例如内存不足)。

正如其他人所说,socket.Close 不会恐慌,而是会返回错误。如果你这样做:

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

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

【讨论】:

以上是关于Golang 中的安全关闭连接的主要内容,如果未能解决你的问题,请参考以下文章

golang sql.DB

golang 连接、操作完mysql, 对mysql的连接会自动关闭,还是必须要手动关闭?

golang :连接数据库闲置断线的问题

golang http client keep-alive最大连接数

Golang 通用连接池

golang中的Mutex和RWMutex