【发布时间】:2019-01-02 20:50:50
【问题描述】:
我在从父进程发送信号并在子进程中接收信号时遇到问题。
这是子进程的代码。它在收到 SIGINT 时退出。
// child.go
func main() {
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt)
fmt.Println("started")
<-stop
fmt.Println("stopped")
}
这是父进程。它启动 child.go,发送 SIGINT,然后等待它退出。
// 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
}
这段代码应该打印started\nstopped以表明它按预期工作,但它只打印started并挂在cmd.Wait(),这意味着子进程没有收到信号。
当我运行go run child.go 时,它运行良好,所以我认为问题不在于该文件。我了解func (*Process) Signal 在 Windows 上不起作用;我正在使用 Linux。
如何修改代码,让子进程收到父进程发送的信号?
【问题讨论】:
-
子进程不是你的程序,它是
go命令。不要使用go run。 -
@JimB 我尝试从终端使用
go run child.go,然后向它发送一个信号并且它工作。exec.Command的工作方式是否有所不同? -
一方面,
exec.Command不是外壳。但是,它在 shell 中的工作原理是一样的,那么你是如何测试它的呢?