I have a research program with very simple algorithm. When success is coming goroutine should be close (end) via os.Exit(0). I'm wait one day, two day.... What? :)
Here is the simple code
package main
import "os"
func main() {
for {
go func() { os.Exit(0) }()
}
}
And my questions:
Playground: http://play.golang.org/p/GAeOI-1Ksc
On exit (once main goes away, or if os. Exit is called) the goroutines are killed off (no deferred functions are run). Note - to get goroutines to quit a 'broadcast' quit channel can be created - as a closed channel starts to return which means a global quit channel can be included in all selects in goroutines and …
To exit an application in Go, use the os. Exit() function from the os package. It causes the program to terminate immediately. The function takes a status code as an argument where the code zero indicates success and the non-zero an error.
When we send data into the channel using a GoRoutine, it will be blocked until the data is consumed by another GoRoutine. When we receive data from channel using a GoRoutine, it will be blocked until the data is available in the channel.
Typically, you pass the goroutine a (possibly separate) signal channel. That signal channel is used to push a value into when you want the goroutine to stop. The goroutine polls that channel regularly. As soon as it detects a signal, it quits.
You've run into a sticky corner of the Go scheduler. The answer is that os.Exit
does cause the entire process to exit, but the way you had it, the goroutines were never running.
What probably happened was that the for loop kept adding new goroutines to the list of available goroutines, but since the entire process was only running in one OS thread, the Go scheduler never got around to actually scheduling a different goroutine, and just kept running that for loop without ever running any of the goroutines you'd spawned. Try this instead:
package main
import "os"
func main() {
for {
go func() { os.Exit(0) }()
func() {}()
}
}
If you run it on the Go Playground, it should work (in fact, here's a link).
OK, the fact that the above code works while yours doesn't should be pretty mysterious. The reason this works is that the Go scheduler is actually non-preempting. What that means is that unless a given goroutine voluntarily decides to give the scheduler the option to run something else, nothing else will run.
Now obviously you've never written code that includes commands to give the scheduler a chance to run. What happens is that when your code is compiled, the Go compiler automatically inserts these into your code. And here's the key to why the above code works: one of the times that a goroutine might decide to run the scheduler is when a function is called. So by adding the func() {}()
call (which obviously does nothing), we've allowed the compiler to add in a call to the scheduler, giving this code the opportunity to schedule different goroutines. Thus, one of the spawned goroutines runs, calls os.Exit
, and the process exits.
EDIT: The function call itself may not be sufficient in the event that the compiler inlines the call (or, in this case, removes it entirely since it does nothing). runtime.Gosched()
, on the other hand, is guaranteed to work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With