So once we use channels in go does that assure that every one the go routines end or we nonetheless want to make use of waitgroups.
I wrote the under code which has a go routine which listens for indicators.
package deal important
import (
"fmt"
"os"
"os/exec"
"os/sign"
"sync"
"syscall"
)
var pid int
var wg sync.WaitGroup
func important() {
signl := make(chan os.Sign, 1)
sign.Notify(signl)
go func() {
wg.Add(1)
defer wg.Carried out()
for {
sig := <-signl
if sig == syscall.SIGINT && pid != 0 {
cmd := exec.Command("minikube", "cease")
err := cmd.Begin()
fmt.Println("closed minikube")
if err != nil {
fmt.Println("failed to shut minikube : ", err)
}
os.Exit(1)
}
fmt.Println("unknown sign recieveed : ", sig)
}
}()
cmd1 := exec.Command("minikube", "begin")
err := cmd1.Begin()
if err != nil {
fmt.Println("failed to start out minikube : ", err)
}
cmd1.Wait()
fmt.Println("beginning dashboard...")
cmd2 := exec.Command("minikube", "dashboard")
err = cmd2.Begin()
pid = cmd2.Course of.Pid
fmt.Println("pid", pid)
if err != nil {
fmt.Println("did not open dashboard : ", err)
}
wg.Wait()
}
in above code is wait group ineffective ?
Whats up there. In code above your program is not going to exit till goroutine exits first. Since there may be an infinite loop contained in the goroutine, it’ll by no means exit by itself. Every thing relies on how and what precisely you are attempting to attain. If it’s some kind of a swish shutdown to run some clean-ups or no matter, I exploit one thing like this:
func exitCtx(mother or father context.Context) (context.Context, context.CancelFunc) {
ctx, cancel := context.WithCancel(mother or father)
go func() {
osSignalCh := make(chan os.Sign, 1)
defer func() {
cancel()
sign.Cease(osSignalCh)
shut(osSignalCh)
}()
sign.Notify(
osSignalCh,
syscall.SIGINT,
syscall.SIGTERM,
os.Interrupt,
)
choose {
case <-ctx.Carried out():
return
case <-osSignalCh:
fmt.Println()
return
}
}()
return ctx, cancel
}
In case for those who simply wish to execute some code in goroutine after which exit your program when all of it completed, then sure, it’s good to sync them by yourself, as a result of it will likely be killed as quickly as important exits. One thing like this:
func DoSomething(ctx context.Context) chan error {
finished := make(chan error, 1)
go func() {
defer shut(finished)
errBuf := errbuf.NewErrorsBuffer()
var wg sync.WaitGroup
wg.Add(numOfProcesses)
for i := 0; i < numOfProcesses; i++ {
go func() {
defer wg.Carried out()
for j := vary dataChannel {
if err := doTheThing(j); err != nil {
errBuf.Add(err)
}
}
}()
}
wg.Wait()
finished <- errBuf.Err()
}()
return finished
}
1 Like
Thanks this was very useful.