Take the following code snippet:
func main() {
ch := make(chan int)
quit := make(chan int)
go func() {
for {
ch <- querySomePeriodicThing()
}
}()
// ...
loop:
for {
select {
case <-ch: handlePeriodicThing()
case <-quit: break loop
}
}
}
The goroutine should run for the duration of execution. When the select statement receives something from the quit channel, it breaks out of the loop and the program ends, without any attempt to stop the goroutine.
My question: will this have any intermittent adverse effects that are not obvious from running it once or twice? I know that in other languages threads should be cleaned up (i.e., exited) before the program ends, but is go different? Assume that querySomePeriodicThing()
does not open file descriptors or sockets or anything that would be bad to leave open.
As mentioned in the spec, your program will exit when the main
function completes:
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.
So the fact you have other goroutines still running is not a problem from a language point of view. It may still be a problem depending on what your program is doing.
If the goroutine has created some resources that should be cleaned up before program exit, then having execution stop mid-way through might be a problem: in this case, you should make your main
function wait for them to complete first. There is no equivalent to pthread_join
, so you will need to code this yourself (e.g. by using a channel or sync.WaitGroup
).
Note that for some resources are automatically cleaned up by the operating system on process exit (e.g. open files, file locks, etc), so in some cases no special clean up will be necessary