代码之家  ›  专栏  ›  技术社区  ›  MakotoE

如何向子进程发送信号?

  •  0
  • MakotoE  · 技术社区  · 6 年前

    我无法从父进程发送信号并在子进程中接收它。

    这是子进程的代码。当它收到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。

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

    1 回复  |  直到 6 年前
        1
  •  2
  •   thst    6 年前

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

    go run child.go 将编译 child 并按照自己的流程执行。如果你运行 ps 之后 去跑步吧。 ,您将看到两个进程正在运行。

    你所观察和发出信号的过程是 go 可执行文件,而不是 小孩 .

    替换 exec.Command("go", "run", "child.go") 使用已编译的二进制文件 exec.Command("child") 它应该是有效的。