goroutine异常导致程序崩溃

goroutine异常问题
刚从java转go,有些地方的使用不是很清楚,请教个问题 golang中接口创建了3个子线程分别请求数据,做了defer recover()的异常捕捉机制,但程序任然会异常崩溃,日志信息如下:

img

代码逻辑如下图,子线程里面是个http请求数据的过程

img


有没有优化的方案,能避免出现这种goroutine的异常问题

以下内容部分参考ChatGPT模型:


你好,关于你的问题,我认为可能是你的子线程抛出了异常但没有被及时捕获,导致程序崩溃。具体解决思路如下:

  1. 确保所有子线程的异常都被捕获并处理。可以在每个子线程中使用recover()来捕获异常,并将异常信息通过通道传递给主线程。

  2. 在主线程中使用select语句来等待所有子线程的结果,并处理异常信息。如果发现有子线程抛出异常,则在主线程中进行相应的处理,例如打印日志或发送警报。

  3. 确保所有子线程在处理完异常后能够正常退出。可以在每个子线程的defer语句中添加相应的清理操作,例如关闭文件句柄或释放资源。

下面是一个示例代码,其中使用了三个子线程来请求数据,并将结果通过通道传递给主线程。每个子线程在处理异常后都会将异常信息传递给主线程,并在defer语句中进行清理操作。主线程在等待所有子线程的结果时会处理异常信息,并在所有子线程退出后进行最终的清理操作。

package main

import (
    "fmt"
)

func main() {
    resultChan := make(chan int)
    errorChan := make(chan error)
    defer close(resultChan)
    defer close(errorChan)

    // 启动三个子线程
    for i := 0; i < 3; i++ {
        go func() {
            defer func() {
                if err := recover(); err != nil {
                    errorChan <- fmt.Errorf("goroutine error: %v", err)
                }
                // 清理操作
            }()

            // 请求数据
            data, err := requestData()
            if err != nil {
                panic(err)
            }
            resultChan <- data
        }()
    }

    // 等待所有子线程的结果
    var results []int
    for i := 0; i < 3; i++ {
        select {
        case data := <-resultChan:
            results = append(results, data)
        case err := <-errorChan:
            fmt.Println(err)
        }
    }

    // 处理结果
    fmt.Println(results)

    // 最终清理操作
}

func requestData() (int, error) {
    // 请求数据
    return 0, nil
}

希望以上解决思路能够对你有所帮助。如果还有不清楚的地方,请随时提出。


如果我的建议对您有帮助、请点击采纳、祝您生活愉快

我这边的IO wait的异常和线程本身没有关系,是由于在每个子线程里面对全局的map[string]interface{} 进行了赋值操作导致的,golang中map是线程不安全的,接口被大量请求,且出现了网络波动或其他异常情况时,就会导致这种情况发生。后面改成用chan的方式将子线程的结果返回给主线程再进行赋值的方式后,就不会出现这种情况了。