防止 Ctrl+C 中断 Golang 中的 exec.Command [英] Prevent Ctrl+C from interrupting exec.Command in Golang

查看:75
本文介绍了防止 Ctrl+C 中断 Golang 中的 exec.Command的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到,即使通过 signal.Notify 拦截了中断调用,以 exec.Command 开始的进程也会被中断.我已经完成了以下示例来说明问题:

I've noticed that processes started with exec.Command get interrupted even when the interrupt call has been intercepted via signal.Notify. I've done the following example to show the issue:

package main

import (
    "log"
    "os"
    "os/exec"
    "os/signal"
    "syscall"
)

func sleep() {
    log.Println("Sleep start")
    cmd := exec.Command("sleep", "60")
    cmd.Run()
    log.Println("Sleep stop")
}

func main() {
    var doneChannel = make(chan bool)

    go sleep()

    c := make(chan os.Signal, 1)
    signal.Notify(c, os.Interrupt)
    signal.Notify(c, syscall.SIGTERM)
    go func() {
        <-c
        log.Println("Receved Ctrl + C")
    }()

    <-doneChannel
}

如果在此程序运行时按下 Ctrl+C,它将打印:

If Ctrl+C is pressed while this program is running, it's going to print:

2015/10/16 10:05:50 Sleep start
^C2015/10/16 10:05:52 Receved Ctrl + C
2015/10/16 10:05:52 Sleep stop

显示 sleep 命令被中断.虽然 Ctrl+C 被成功捕获,但主程序并没有退出,只是 sleep 命令受到影响.

showing that the sleep commands gets interrupted. Ctrl+C is successfully caught though and the main program doesn't quit, it's just the sleep commands that gets affected.

知道如何防止这种情况发生吗?

Any idea how to prevent this from happening?

推荐答案

当你按下 ctrl+c 时,shell 会向整个进程组发出信号.如果直接给父进程发信号,子进程不会收到信号.

The shell will signal the entire process group when you press ctrl+c. If you signal the parent process directly, the child process won't receive the signal.

为防止 shell 向子进程发出信号,您需要在其自己的进程组中使用 syscall.SysProcAttr 在启动进程之前

To prevent the shell from signaling the children, you need to start the command in its own process group with with the Setpgid and Pgid fields in syscall.SysProcAttr before starting the processes

cmd := exec.Command("sleep", "60")
cmd.SysProcAttr = &syscall.SysProcAttr{
    Setpgid: true,
}

这篇关于防止 Ctrl+C 中断 Golang 中的 exec.Command的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆