防止 Ctrl+C 中断 Golang 中的 exec.Command [英] Prevent Ctrl+C from interrupting exec.Command in Golang
问题描述
我注意到,即使通过 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屋!