全部,
我正在编写一个涉及具有多个故障点的 tcp 流量的程序,并且我希望能够在错误条件下顺利退出 goroutine 而不会产生编码开销。
这是一些伪代码:
func main() {
l, err := net.Listen(CONN_TYPE, CONN_HOST+":"+ CONN_PORT)
for {
// Listen for an incoming connection.
conn, err := l.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
os.Exit(1)
}
done_flag := make(chan bool, 1)
// Handle connections in a new goroutine.
go func() {
conn.Write([]byte("string1\n"))
conn.Write([]byte("string2\n"))
...
}()
}
}
现在,我要避免的是以下带有连接语句的代码,我将代码包装在 goroutine 内的错误处理中(如下所示):
go func() {
if (_err := _send_ack(conn, "string1\n"); _err != nil {
done_flag <- true
}
if (_err := _send_ack(conn, "string2\n"); _err != nil {
done_flag <- true
}
}()
相反,如果存在连接问题,我宁愿将整个事情短路,然后立即退出 goroutine 并出现错误 - 我宁愿不必担心我如何构建代码。也许我可以进一步包装 _send_ack 并将通道作为函数参数发送 - 但如果程序变得高度分层,那将变得不确定。例如,我可能有一个由多个 func 组成的 goroutine,每个 func 处理不同的 tcp 会话 - 我不想在我的子例程中乱扔额外的通道参数来在调用堆栈上下传播通道以防万一我必须设置一个完成标志。此外,还有一个问题是在设置完成标志之后 goroutine 会发生什么以及如何在调用者中处理它。
如果我在 python、perl 或 C++ 中工作,我会抛出一个异常,该异常已附加到发生错误的堆栈跟踪,然后在调用者中处理此错误。但是由于 golang 没有异常,我希望有一种方法可以在不实际退出主程序的情况下停止 goroutine 冷态 - 即:设置一个通道以产生相关错误,然后在该点停止执行。
我看到了恐慌功能,但我不确定它的副作用。你能在不影响主程序的情况下从 goroutine 中恐慌(),或者有没有办法智能地短路 goroutine 而没有副作用,也许返回类似于异常的东西,带有堆栈跟踪和错误?或者,什么是干净的错误处理这样的分层程序的建议方法?
非常感谢您的帮助 - 我是 golang 的新手,它可能会显示出来。
埃德