You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让.NET 6 systemd服务启动的子进程在服务停止后不被终止?

问题分析与解决方案

当你的.NET 6应用以systemd服务运行时,启动的子进程会被纳入systemd为该服务创建的**控制组(cgroup)**中。systemd默认使用KillMode=control-group策略,停止服务时会向整个控制组内的所有进程发送SIGTERM信号,这就是子进程和父进程同时被终止的核心原因。

要让子进程在父服务停止后继续运行,可以通过以下两种方式解决:

方法一:修改systemd服务配置

编辑你的应用服务文件(通常位于/etc/systemd/system/目录下,命名类似your-app.service),在[Service]段添加KillMode=process:

[Service]
# 保留原有配置项
KillMode=process

KillMode=process会让systemd仅向服务的主进程发送终止信号,不会处理控制组内的其他子进程,子进程将继续独立运行。

修改后执行以下命令重新加载配置并重启服务:

sudo systemctl daemon-reload
sudo systemctl restart your-app.service

方法二:在.NET代码中让子进程脱离控制组与会话

通过调整ProcessStartInfo的配置,让子进程脱离父进程的会话和systemd的控制组:

方式1:使用setsid命令启动子进程

setsid会为子进程创建一个新的会话,使其脱离父进程的会话组,从而不会收到systemd发送给父进程组的信号:

var process = Process.Start(new ProcessStartInfo
{
    FileName = "/usr/bin/setsid",
    Arguments = "foo bar",
    UseShellExecute = false
});

方式2:设置子进程的控制组为根目录

通过环境变量指定子进程的控制组为根cgroup,使其脱离服务的控制组:

var process = Process.Start(new ProcessStartInfo
{
    FileName = "foo",
    Arguments = "bar",
    UseShellExecute = false,
    RedirectStandardInput = false,
    RedirectStandardOutput = false,
    RedirectStandardError = false,
    EnvironmentVariables =
    {
        {"CGROUP_PATH", "/"}
    }
});

内容的提问来源于stack exchange,提问作者Fabian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 13:18:07