lau*_*ent 3 multithreading subprocess go sigint goroutine
我注意到,exec.Command即使通过中断调用中断调用,进程也会中断signal.Notify.我已经完成了以下示例来说明问题:
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
}
Run Code Online (Sandbox Code Playgroud)
如果在此程序运行时按下Ctrl + C,它将打印:
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
Run Code Online (Sandbox Code Playgroud)
显示sleep命令被中断.虽然Ctrl + C已成功捕获并且主程序未退出,但它只是sleep受到影响的命令.
知道如何防止这种情况发生吗?
当您按下时,shell将发出整个进程组的信号ctrl+c.如果直接向父进程发出信号,子进程将不会收到信号.
为了防止shell向子节点发送信号,您需要在启动进程之前在其自己的进程组中使用Setpgid和Pgid字段启动命令syscall.SysProcAttr
cmd := exec.Command("sleep", "60")
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
}
Run Code Online (Sandbox Code Playgroud)