英文:
Go preempt can exit out of a loop
问题
我正在尝试理解如何使用"go"来抢占循环或阻塞调用。我了解到,通过SIGURG
信号,阻塞子例程堆栈会被破坏,并且会进行JMP以抢占函数。然而,当子例程再次有机会执行时,如何退出循环呢?就像在这篇文章中提到的那样:https://developpaper.com/goroutine-preemptive-scheduling-with-new-features-of-go-1-14/
使用go 1.13,程序会永远挂起:
$ docker run -it --rm app13:latest
The program starts ...
使用go 1.14,循环会退出:
$ docker run -it --rm app14:latest
The program starts ...
I got scheduled!
有没有一些好的文档或论文可以阅读,以了解这种行为。对我来说,这看起来像是一个bug,一个循环就是一个循环,无论是否被抢占,它怎么可能退出呢?
英文:
I am trying to understand how "go" can preempt a loop or blocking call. I understand that with SIGURG
signal, the blocking surbroutine stack is poisoned and a JMP is made to preempt function. However when the subroutine is given a chance again to execute, how can it exit the loop as is mentioned in the article https://developpaper.com/goroutine-preemptive-scheduling-with-new-features-of-go-1-14/
package main
import (
"fmt"
"runtime"
"time"
)
func main() {
runtime.GOMAXPROCS(1)
fmt.Println("The program starts ...")
go func() {
for {
}
}()
time.Sleep(time.Second)
fmt.Println("I got scheduled!")
}
With go 1.13, the program hangs forever
$ docker run -it --rm app13:latest
The program starts ...
With go 1.14, the loop exits?
$ docker run -it --rm app14:latest
The program starts ...
I got scheduled!
Is there any good documentation, paper i can read to understand this behavior. To me this looks like a bug, a loop is a loop, how can it exit irrespective it is prempt or not.
答案1
得分: 1
《Go语言规范》(https://go.dev/ref/spec#Program_execution)中提到:
程序的执行从初始化主包开始,然后调用main函数。当该函数调用返回时,程序退出。它不会等待其他(非主)goroutine完成。
Go 1.14及更高版本中的抢占式调度确保执行main函数的goroutine运行,并且main函数返回后程序退出。当程序退出时,任何正在运行的goroutine都将停止存在。
在没有抢占式调度的情况下,执行main函数的goroutine可能不会运行。如果main函数不返回,程序将挂起。
英文:
The Go Language Specification says:
> Program execution begins by initializing the main package and then invoking the function main. When that function invocation returns, the program exits. It does not wait for other (non-main) goroutines to complete.
Preemption in Go 1.14 and later ensures that the goroutine executing the main function runs and that that main function returns. The program exits when the main function returns. Any running goroutines cease to exist when the program exits.
In the absence of preemption, the goroutine executing the main function may not run. The program hangs if the main function does not return.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论