Reputation: 2109
I'm having trouble sending a signal from a parent process and receiving it in the child process.
This is the code for the child process. It exits when it receives SIGINT.
// child.go
func main() {
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt)
fmt.Println("started")
<-stop
fmt.Println("stopped")
}
This is the parent process. It starts child.go
, sends SIGINT, then waits for it to exit.
// main.go
func main() {
// Start child process
cmd := exec.Command("go", "run", "child.go")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Start()
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Start: " + err.Error())
return
}
// Wait, then send signal
time.Sleep(time.Millisecond * 500)
err = cmd.Process.Signal(os.Interrupt)
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Signal: " + err.Error())
return
}
// Wait for child process to finish
err = cmd.Wait()
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Wait: " + err.Error())
}
return
}
This code should print started\nstopped
to show that it worked as expected, but it only prints started
and hangs at cmd.Wait()
, meaning the child process did not receive the signal.
When I run go run child.go
it works fine, so I don't think the problem is with that file. I understand that func (*Process) Signal
doesn't work on Windows; I am using Linux.
How can I fix the code so that the child process gets the signal sent by the parent process?
Upvotes: 3
Views: 4726
Reputation: 4602
As mentioned by @JimB in the comments section, the go run
is your problem.
go run child.go
will compile child
and execute it as it's own process. If you run a ps
after go run child.go
, you will see two processes running.
The process you are watching and signalling is the go
executable, not the child
.
Replace the exec.Command("go", "run", "child.go")
with the compiled binary exec.Command("child")
and it should work.
Upvotes: 5