主进程从systemd启动时不能分离subprocess

我想生成长时间运行的subprocess,在主进程重启/死亡时生存下来。 从terminal运行时,这工作正常:

$ cat exectest.go package main import ( "log" "os" "os/exec" "syscall" "time" ) func main() { if len(os.Args) == 2 && os.Args[1] == "child" { for { time.Sleep(time.Second) } } else { cmd := exec.Command(os.Args[0], "child") cmd.SysProcAttr = &syscall.SysProcAttr{Setsid: true} log.Printf("child exited: %v", cmd.Run()) } } $ go build $ ./exectest ^Z [1]+ Stopped ./exectest $ bg [1]+ ./exectest & $ ps -ef | grep exectest | grep -v grep | grep -v vim snowm 7914 5650 0 23:44 pts/7 00:00:00 ./exectest snowm 7916 7914 0 23:44 ? 00:00:00 ./exectest child $ kill -INT 7914 # kill parent process [1]+ Exit 2 ./exectest $ ps -ef | grep exectest | grep -v grep | grep -v vim snowm 7916 1 0 23:44 ? 00:00:00 ./exectest child 

请注意,父进程被终止后,subprocess仍然存在。 但是,如果我从systemd启动这个主进程就像这样…

 [snowm@localhost exectest]$ cat /etc/systemd/system/exectest.service [Unit] Description=ExecTest [Service] Type=simple ExecStart=/home/snowm/src/exectest/exectest User=snowm [Install] WantedBy=multi-user.target $ sudo systemctl enable exectest ln -s '/etc/systemd/system/exectest.service' '/etc/systemd/system/multi-user.target.wants/exectest.service' $ sudo systemctl start exectest 

…当我杀死主要过程时,孩子也死了:

 $ ps -ef | grep exectest | grep -v grep | grep -v vim snowm 8132 1 0 23:55 ? 00:00:00 /home/snowm/src/exectest/exectest snowm 8134 8132 0 23:55 ? 00:00:00 /home/snowm/src/exectest/exectest child $ kill -INT 8132 $ ps -ef | grep exectest | grep -v grep | grep -v vim $ 

我怎样才能让孩子生存下

在CentOS Linux release 7.1.1503(Core)下运行go版本go1.4.2 linux / amd64。

Solutions Collecting From Web of "主进程从systemd启动时不能分离subprocess"

解决方法是添加

 KillMode=process 

到服务块。 默认值是control-group ,这意味着systemd会清理所有的子进程。

从人systemd.kill

KillMode =指定如何杀死这个单元的进程。 控制组,过程之一,混合,没有。

如果设置为control-group,则本机控制组中的所有剩余进程将在单元停止时被终止(对于服务:执行停止命令之后,由ExecStop =配置)。 如果设置为进程,则只有主进程本身被终止。 如果设置为混合,则SIGTERM信号(见下文)被发送到主进程,而后续SIGKILL信号(见下文)被发送到设备控制组的所有其余进程。 如果设置为none,则不会有进程被终止。 在这种情况下,在单元停止时只执行停止命令,否则不会停止进程。 停止后保持的进程保留在其控制组中,并且控制组在停止后继续存在,除非它是空的。