为什么从杜松子酒的处理程序开始例行工作直到结束

Why go routine works till end from a Gin's handler

我知道如果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...

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


但是,如下面的代码所示,如​​果我们从Gin的handle开始gorouting,即使response发送了,计算Fibonacci sum结果的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.

问题:

  1. 为什么从 gin 句柄开始的 goroutine 没有结束 在杜松子酒的句柄发送响应后强行发送响应?
  2. handle的goroutine是不是应该在handle之后结束 回复已发送?
  3. handle启动的goroutine是不是应该强行结束 句柄上的 goroutine 结束?

I know that if the goroutine B is started from a certain goroutine A, and if the goroutine A ends, no matter how far does goroutine B steps, it will be ended up forcefully.

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

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

这也发生在你的例子中。

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

如果您稍微更改示例代码,您会发现您的程序还可以计算斐波那契和。

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