如何在发生错误时在内部干净地停止goroutines
全部, 我正在编写一个涉及tcp流量的程序,该程序存在多个故障点 我希望能够在错误情况下顺利退出goroutine,而不会产生编码开销 下面是一些伪代码:如何在发生错误时在内部干净地停止goroutines,go,exception,error-handling,tcp,goroutine,Go,Exception,Error Handling,Tcp,Goroutine,全部, 我正在编写一个涉及tcp流量的程序,该程序存在多个故障点 我希望能够在错误情况下顺利退出goroutine,而不会产生编码开销 下面是一些伪代码: func main() { l, err := net.Listen(CONN_TYPE, CONN_HOST+":"+ CONN_PORT) for {
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(){
如果(_err:=_send_ack(conn,“string1\n”);_err!=nil{
golang建议使用显式错误而不是隐式异常
//为了代码的简单性
func doSendACKImpl(conn net.conn)错误{
如果错误:发送确认(conn,“string1\n”);错误!=nil{
返回错误
}
如果错误:=\u发送\u确认(conn,“string2\n”);错误!=nil{
返回错误
}
归零
}
func main(){
l、 错误:=net.Listen(连接类型,连接主机+”:“+连接端口)
为了{
//侦听传入的连接。
conn,err:=l.Accept()
如果错误!=零{
fmt.Println(“错误接受:”,err.Error())
操作系统退出(1)
}
//可以更改为自定义ResponseType,此处使用错误进行演示
workRes:=make(chan错误,1)
go func(){
//返回写回通道
workRes使用context.context
,或者使用一个频道并在出现错误时关闭频道。Burak-好的,因此您建议以频道的形式传递一个上下文并保留其状态信息,然后关闭频道。不完全是这样。通常context.context
用于此目的,并且在错误,取消了上下文,因此共享相同上下文的任何goroutine都可以检测到取消。这还允许使用上下文传递其他信息。如果您关心的只是取消,则可以传递一个通道,并在发生错误时关闭它,以便所有goroutine都可以检测到取消。您必须每秒钟检查一次通道o经常在所有的社交场合。
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
}
}()
func main() {
l, _ := net.Listen(CONN_TYPE, CONN_HOST+":"+CONN_PORT)
// more result buffer size
const workSize int = 100
// can change to self defined ResponseType, here use error for demo
workResBuffer := make(chan error, workSize)
// goroutine collect result
go func() {
// get all result from worker responses
for resError := range workResBuffer {
fmt.Printf("meet error %s", resError)
}
}()
for {
// Listen for an incoming connection.
conn, err := l.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
os.Exit(1)
}
// TODO: limit the goroutine number
go func() {
// return write back to channel
workResBuffer <- doSendACKImpl(conn)
}()
}
}