如何向子进程发送信号?

Mak*_*toE 3 signals go

我在从父进程发送信号并在子进程中接收信号时遇到问题。

这是子进程的代码。当它收到 SIGINT 时退出。

// child.go
func main() {
    stop := make(chan os.Signal, 1)
    signal.Notify(stop, os.Interrupt)
    fmt.Println("started")

    <-stop
    fmt.Println("stopped")
}
Run Code Online (Sandbox Code Playgroud)

这是父进程。它启动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
}
Run Code Online (Sandbox Code Playgroud)

此代码应该打印started\nstopped以表明它按预期工作,但它仅打印started并挂起于cmd.Wait(),这意味着子进程没有收到信号。

当我运行时go run child.go它工作正常,所以我不认为问题出在该文件上。我知道这func (*Process) Signal在 Windows 上不起作用;我正在使用Linux。

如何修复代码以便子进程获取父进程发送的信号?

ths*_*hst 5

正如 @JimB 在评论部分提到的,这go run是你的问题。

go run child.go将编译child并执行它作为它自己的进程。如果您运行psafter go run child.go,您将看到两个进程正在运行。

您正在观察和发出信号的进程是go可执行文件,而不是child.

将 替换exec.Command("go", "run", "child.go")为已编译的二进制文件exec.Command("child"),它应该可以工作。