如何在发生错误时在内部干净地停止goroutines

如何在发生错误时在内部干净地停止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 {

全部,

我正在编写一个涉及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(){
如果(_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)
        }()
    }
}