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

如何让systemd将服务标记为active (exited)?C#程序实现方法

解决systemd服务始终处于activating状态的问题

一、修改systemd服务配置文件

你的服务一直处于activating状态,核心原因是Type=oneshot这个配置不适用于长期运行的后台服务:

  • oneshot类型针对一次性执行的任务,systemd会持续等待进程退出,才会将服务标记为active状态。
  • 对于长期运行的控制台服务,应使用Type=simple(默认值,可省略),systemd启动进程后即刻判定服务启动完成,只要进程持续运行,服务就会处于active状态。

修改后的服务配置文件示例:

[Unit]
Description=xreen
Requires=network.target
After=network.target

[Service]
ExecStart=/path/to/console-programm
WorkingDirectory=/path/to/dir
# 改用simple类型,适配前台运行的长期服务
Type=simple
# 可选:进程异常退出时自动重启
Restart=always
# 可选:设置服务运行的用户权限
User=your-user

修改后执行以下命令让配置生效:

sudo systemctl daemon-reload
sudo systemctl restart xreen

二、C#程序的优化(无需主动修改systemd服务状态)

systemd通过进程的运行状态管理服务状态,不需要在C#代码里主动修改服务状态。你现有代码已能处理SIGTERM信号,可补充以下优化点:

  1. 同时监听SIGINT信号(对应Ctrl+C或systemd的stop命令),让退出逻辑覆盖更全面:
private static ManualResetEventSlim _quitProgramEvent = new();

private static void Main(string[] args)
{
    // 同时监听SIGTERM和SIGINT退出信号
    PosixSignalRegistration.Create(PosixSignal.SIGTERM, _ => _quitProgramEvent.Set());
    PosixSignalRegistration.Create(PosixSignal.SIGINT, _ => _quitProgramEvent.Set());

    Thread t = new(InfiniteLoop);
    t.IsBackground = true;
    t.Start();

    _quitProgramEvent.Wait();
    // 可选:添加退出前的资源清理逻辑
    Console.WriteLine("服务正在退出...");
}
  1. 确保InfiniteLoop方法包含退出判断,避免线程无法终止:
private static void InfiniteLoop()
{
    while (!_quitProgramEvent.IsSet)
    {
        // 你的业务逻辑代码
        Thread.Sleep(1000);
    }
}

总结

  • 核心解决步骤是修改systemd服务的Type配置,从oneshot改为simple,让systemd正确识别长期运行的服务状态。
  • C#程序只需保证正常处理退出信号、持续稳定运行即可,无需主动修改systemd的服务状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 15:07:03