Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ensure executables called in Go Process get killed when Process is killed

Tags:

go

I have some code that in Go (golang), has a few different threads running a separate executable. I want to ensure that if a user kills my process in Go, that I have a way of killing the executables I've called, is there a way to do that?

like image 350
Ali Sakr Avatar asked Jan 11 '16 20:01

Ali Sakr


2 Answers

The only ways to ensure that the child process is killed, is to start it in the same process group, and kill the process group as a whole, or set Pdeadthsig in the syscall.SetProcAddr.

You can setup a signal handler for common signals like SIG_INT and SIG_TERM, and kill your child processes before exiting, but since you can't catch SIG_KILL that's often not worth the effort.

See: Panic in other goroutine not stopping child process

cmd := exec.Command("./long-process")

cmd.SysProcAttr = &syscall.SysProcAttr{
    Pdeathsig: syscall.SIGTERM,
}
like image 170
JimB Avatar answered Oct 12 '22 08:10

JimB


One possible strategy is to keep a list of processes you're running in a global array var childProcesses = make([]*os.Process, 0) and append to it every time you start a process.

Have your own Exit function. Make sure that you never call os.Exit anywhere in your code, and always call your own Exit function instead. Your Exit function will kill all the childProcesses

for _, p := range childProcesses {
    p.Kill()
}

Handle signals so they go through your own exit function, for example by doing this during initialization (somewhere near the top of your main function)

sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM, syscall.SIGKILL, syscall.SIGQUIT)
goUnsafe(func() {
    var signal = <-sigs
    log.Println("Got Signal", signal)
    Exit(0)
})
like image 27
user10753492 Avatar answered Oct 12 '22 10:10

user10753492