While SayHello()
executes as expected, the goroutine prints nothing.
package main
import \"fmt\"
func SayHello() {
for i := 0; i < 10
A Go program exits when the main
function returns.
One option is to use something like sync.WaitGroup
to wait on the other goroutines that main
has spawned before returning from main
.
Another option is to call runtime.Goexit()
in main
. From the godoc:
Goexit terminates the goroutine that calls it. No other goroutine is affected. Goexit runs all deferred calls before terminating the goroutine. Because Goexit is not a panic, any recover calls in those deferred functions will return nil.
Calling Goexit from the main goroutine terminates that goroutine without func main returning. Since func main has not returned, the program continues execution of other goroutines. If all other goroutines exit, the program crashes.
This allows main goroutine to stop executing while the background routines continue to execute. For example:
package main
import (
"fmt"
"runtime"
"time"
)
func f() {
for i := 0; ; i++ {
fmt.Println(i)
time.Sleep(10 * time.Millisecond)
}
}
func main() {
go f()
runtime.Goexit()
}
This can be cleaner than blocking forever in the main function, especially for programs that are infinite. One downside is that if all of the goroutines of a process return or exit (including the main goroutine), Go will detect this as an error and panic:
fatal error: no goroutines (main called runtime.Goexit) - deadlock!
To avoid this, at least one goroutine must call os.Exit
before it returns. Calling os.Exit(0)
immediately terminates the program and indicates that it did so without error. For example:
package main
import (
"fmt"
"os"
"runtime"
"time"
)
func f() {
for i := 0; i < 10; i++ {
fmt.Println(i)
time.Sleep(10 * time.Millisecond)
}
os.Exit(0)
}
func main() {
go f()
runtime.Goexit()
}