When main exits, the program terminates regardless of the state of other goroutines. You can test this by adding select{}
at the end of your main function. This will cause main to never exit and you will see the other goroutines run.
If you want your program to exit cleanly (without a deadlock) when both goroutines complete, you need to use something like a channel or sync.Waitgroup to coordinate main ending when everything is complete.
Example using sync.Waitgroup:
package main
import (
"fmt"
"sync"
)
func f(from string, wg *sync.WaitGroup) {
for i := 0; i < 3; i++ {
fmt.Println(from, ":", i)
}
wg.Done()
}
func main() {
wg := new(sync.WaitGroup)
wg.Add(2)
go f("direct", wg)
go f("redirect", wg)
wg.Wait()
}
Example using channels:
package main
import (
"fmt"
)
func f(from string, ch chan<- bool) {
for i := 0; i < 3; i++ {
fmt.Println(from, ":", i)
}
ch <- true
}
func main() {
ch := make(chan bool)
go f("direct", ch)
go f("redirect", ch)
<-ch
<-ch
}