0

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.

Rohit Sharma
  • 6,136
  • 3
  • 28
  • 47
  • 2
    It doesn’t exit the loop, it simply preempts it alowing main to continue. The loop “exits” by virtue of the process terminating. – JimB Jun 10 '22 at 02:49
  • 1
    You have no synchronization code; the end of the main goroutine and the loop goroutine have no defined order with respect to each other. – Hymns For Disco Jun 10 '22 at 03:51

1 Answers1

1

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.

  • Sorry this is not clear to me, if function is in a tight loop, it is then preempted and yielded, and then resumed, would it not resume back into the loop? How did it go out of the loop? Are we not resuming back into anon function? – Rohit Sharma Jun 10 '22 at 01:28
  • 1
    Yes, the goroutine will resume back into the loop when the goroutine is resumed. However, the goroutine ceases to exist when the main function returns. –  Jun 10 '22 at 01:35