为啥 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 中读取?