微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

linux – 从systemd启动主进程时无法分离子进程

我想生成长时间运行的子进程,这些进程在主进程重新启动/死亡时仍然存在.从终端运行时这很好用:

$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

请注意,在父进程被终止后,子进程仍处于活动状态.但是,如果我像这样从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版本7.1.1503(Core)下运行go版本go1.4.2 linux / amd64.

解决方法:

解决方案是添加

KillMode=process

到服务区.默认值是control-group,这意味着systemd会清除所有子进程.

man systemd.kill

KillMode= Specifies how processes of this unit shall be killed. One of
control-group, process, mixed, none.

If set to control-group, all remaining processes in the control group
of this unit will be killed on unit stop (for services: after the stop
command is executed, as configured with ExecStop=). If set to process,
only the main process itself is killed. If set to mixed, the SIGTERM
signal (see below) is sent to the main process while the subsequent
SIGKILL signal (see below) is sent to all remaining processes of the
unit’s control group. If set to none, no process is killed. In this
case, only the stop command will be executed on unit stop, but no
process be killed otherwise. Processes remaining alive after stop are
left in their control group and the control group continues to exist
after stop unless it is empty.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐