So when we use channels in go does that guarantee that all the go routines finish or we still need to use waitgroups.
I wrote the below code which has a go routine which listens for signals.
package main
import (
"fmt"
"os"
"os/exec"
"os/signal"
"sync"
"syscall"
)
var pid int
var wg sync.WaitGroup
func main() {
signl := make(chan os.Signal, 1)
signal.Notify(signl)
go func() {
wg.Add(1)
defer wg.Done()
for {
sig := <-signl
if sig == syscall.SIGINT && pid != 0 {
cmd := exec.Command("minikube", "stop")
err := cmd.Start()
fmt.Println("closed minikube")
if err != nil {
fmt.Println("failed to close minikube : ", err)
}
os.Exit(1)
}
fmt.Println("unknown signal recieveed : ", sig)
}
}()
cmd1 := exec.Command("minikube", "start")
err := cmd1.Start()
if err != nil {
fmt.Println("failed to start minikube : ", err)
}
cmd1.Wait()
fmt.Println("starting dashboard...")
cmd2 := exec.Command("minikube", "dashboard")
err = cmd2.Start()
pid = cmd2.Process.Pid
fmt.Println("pid", pid)
if err != nil {
fmt.Println("failed to open dashboard : ", err)
}
wg.Wait()
}
Hello there. In code above your program will not exit until goroutine exits first. Since there is an endless loop inside the goroutine, it will never exit on its own. Everything depends on how and what exactly you are trying to achieve. If it’s some sort of a graceful shutdown to run some clean-ups or whatever, I use something like this:
In case if you just want to execute some code in goroutine and then exit your program when all of it finished, then yes, you need to sync them on your own, because it will be killed as soon as main exits. Something like this:
func DoSomething(ctx context.Context) chan error {
done := make(chan error, 1)
go func() {
defer close(done)
errBuf := errbuf.NewErrorsBuffer()
var wg sync.WaitGroup
wg.Add(numOfProcesses)
for i := 0; i < numOfProcesses; i++ {
go func() {
defer wg.Done()
for j := range dataChannel {
if err := doTheThing(j); err != nil {
errBuf.Add(err)
}
}
}()
}
wg.Wait()
done <- errBuf.Err()
}()
return done
}