为啥 goroutine 从杜松子酒的处理程序一直有效[关闭]

Posted

技术标签:

【中文标题】为啥 goroutine 从杜松子酒的处理程序一直有效[关闭]【英文标题】:Why go routine works till end from a Gin's handler [closed]为什么 goroutine 从杜松子酒的处理程序一直有效[关闭] 【发布时间】:2022-01-21 18:50:21 【问题描述】:

我知道如果goroutine B是从某个goroutine A开始的,如果goroutine A结束了,goroutine B不管走多远都会被强行结束。

func main()  
    go simulateGinAPI()
    fmt.Println("finish...")


func simulateGinAPI() 
    fmt.Println("ginAPI....")
    go backgroundProcess()



func backgroundProcess() 
    fmt.Println("calculating...")
    fmt.Println(calculate(45))


func calculate(x int) int 
    if x < 2 
        return x
    
    return calculate(x-1) + calculate(x-2)

输出

finish...

如输出日志所示。斐波那契和的结果不会被注销,而是只会“完成”被注销。


但是,如下面的代码所示,如​​果我们从 Gin 的句柄开始 gorouting,即使发送了响应,用于计算斐波那契和结果的 goroutine 仍然会运行到最后。


func main() 
    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) 
        go backgroundProcess()
        c.JSON(200, gin.H
            "message": "pong",
        )
    )
    r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")


func simulateGinAPI() 
    fmt.Println("ginAPI....")
    go backgroundProcess()



func backgroundProcess() 
    fmt.Println("calculating...")
    fmt.Println(calculate(45))


func calculate(x int) int 
    if x < 2 
        return x
    
    return calculate(x-1) + calculate(x-2)

输出

[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080
calculating...
[GIN] 2021/12/20 - 11:31:46 | 200 |      56.425µs |             ::1 | GET      "/ping"
1134903170 <- result of Fibonacci's sum.

问题:

    为什么 goroutine 从 gin 的句柄开始没有结束 在杜松子酒的句柄发送响应之后强行发送响应? 句柄的 goroutine 不应该在 已发送响应? 从句柄开始的goroutine不应该被强行结束吗 与句柄上的协程结束?

【问题讨论】:

1.在 Go 中,没有办法在外部停止 goroutine,它可能只能自己完成(成功或通过恐慌)2. Go 中没有任何东西需要 3. 没有 【参考方案1】:

我知道如果goroutine B是从某个goroutine A开始的,如果goroutine A结束了,goroutine B不管走多远都会被强行结束。

这是不正确的。如果main函数退出,所有的goroutines也会退出。

但是如果main函数继续运行,虽然goroutine调用者函数退出了,那个goroutine会继续它的进程。

这也发生在你的例子中。

您的示例代码在计算Fibonacci 和之前就退出了。但是您的服务器代码继续运行。这就是代码中出现这种行为的原因。

如果您稍微修改一下示例代码,您会看到您的程序还计算了斐波那契和。

示例如下:https://goplay.tools/snippet/dMCyUqweyu8

【讨论】:

以上是关于为啥 goroutine 从杜松子酒的处理程序一直有效[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何设计 goroutines 程序来处理 api 限制错误

为啥使用goroutine后计算任务的总时间基本一样

为啥在同一个 goroutine 中使用无缓冲通道会导致死锁?

为啥数据被推入通道但从未从接收器 goroutine 中读取?

Golang:为啥增加缓冲通道的大小会消除我的 goroutine 的输出?

golang 多协程注意事项