Go语言中的”preempt”是指在循环中提前退出的意思。

huangapple go评论91阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2022年6月10日 08:47:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/72568024.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定