英文:
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...
正如输出日志所示,斐波那契和的结果没有被记录下来,只有 "finish" 被记录下来。
然而,如下所示的代码,如果我们从 Gin 的处理函数中启动 goroutine,即使响应已经发送,用于计算斐波那契和结果的 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 <- 斐波那契和的结果。
问题:
- 为什么从 Gin 的处理函数中启动的 goroutine 在响应发送后没有被强制结束?
- 响应发送后,处理函数的 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.
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)
}
output
finish...
As the output log shows. Result of Fibonacci sum will not be logged out, instead, only "finish" was logged out.
However, as the code below shows, if we start gorouting from a Gin's handle, even the response was sent, goroutine for calculating the result of Fibonacci sum will still be run to the end.
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)
}
output
[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.
Question:
- Why the goroutine started from handle of gin was not end up
forcefully after the gin's handle send response? - Should not the goroutine of the handle be ended up after the
response was sent? - Should not the goroutine started from handle be ended up forcefully
with the end of the goroutine on the handle?
答案1
得分: 6
我知道,如果 goroutine B 是从某个 goroutine A 启动的,而且如果 goroutine A 结束了,无论 goroutine B 走了多远,它都会被强制结束。
这是不正确的。如果 main
函数退出,所有的 goroutine 也会退出。
但是如果 main
函数继续运行,尽管 goroutine 的调用函数退出了,该 goroutine 仍会继续执行。
你的示例代码在计算 Fibonacci
和之前就退出了。但是你的服务器代码继续运行。这就是代码的行为。
如果你稍微修改一下示例代码,你会发现程序也会计算出 Fibonacci 和。
这是示例代码:https://goplay.tools/snippet/dMCyUqweyu8
英文:
> 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.
It's not correct. If the main
function exits, all the goroutines will be exited too.
But if the main
function continues running, although the goroutine caller function exits, that goroutine will continue its course.
This happened in your example too.
Your example code exits before it could calculate the Fibonacci
sum. But your server code continues running. That's why this behavior from the code.
If you altered your example code a bit, you could see that your program also calculates the Fibonacci sum.
Here's the example: https://goplay.tools/snippet/dMCyUqweyu8
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论