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

如何在Rust中忽略SIGHUP信号

在Rust中忽略SIGHUP信号,让程序脱离终端后持续运行

实现思路

当终端关闭时,系统会向关联进程发送SIGHUP信号,默认行为是终止进程。要让程序继续运行,只需通过signal-hook crate注册一个空的SIGHUP信号处理逻辑,直接忽略该信号即可。

示例:后台秒数写入工具

下面是一个完整的实用示例——程序每秒向文件写入累计运行秒数,关闭终端后依然会持续运行,直到手动用kill命令终止。

首先在Cargo.toml中添加依赖:

[dependencies]
signal-hook = "0.3"

然后编写src/main.rs:

use std::fs::OpenOptions;
use std::io::Write;
use std::thread;
use std::time::Duration;
use signal_hook::{consts::signal::SIGHUP, iterator::Signals};

fn main() -> std::io::Result<()> {
    // 注册SIGHUP信号监听,收到后不做任何处理(忽略信号)
    let mut signals = Signals::new(&[SIGHUP])?;
    thread::spawn(move || {
        for _ in signals.forever() {
            // 空逻辑,直接忽略SIGHUP信号
        }
    });

    // 打印进程ID,方便后续手动终止程序
    println!("程序启动,进程ID:{}", std::process::id());

    // 以追加模式打开目标文件,不存在则创建
    let mut file = OpenOptions::new()
        .create(true)
        .append(true)
        .open("run_log.txt")?;

    let mut seconds = 0;
    loop {
        seconds += 1;
        writeln!(file, "已运行 {} 秒", seconds)?;
        file.flush()?; // 强制写入磁盘,避免缓存丢失
        thread::sleep(Duration::from_secs(1));
    }
}

关键细节说明

  • 信号处理:通过Signals::new创建SIGHUP信号监听器,在子线程中循环接收信号但不执行任何操作,等价于忽略该信号,避免进程被终端关闭触发的SIGHUP终止。
  • 文件写入:使用追加模式打开文件,每次写入后调用flush()确保内容立即落盘,防止程序意外终止时数据滞留在缓存中。
  • 验证方式:启动程序后关闭终端,查看run_log.txt文件,会发现内容仍在持续更新,说明程序已在后台正常运行。

额外提示

  • 如果需要同时忽略其他终端信号(比如Ctrl+C触发的SIGINT),可以在Signals::new的参数中添加SIGINT,同样用空逻辑处理即可。
  • 也可以结合nohup命令启动程序,但通过代码忽略SIGHUP的方式更灵活,无需依赖外部命令。

内容的提问来源于stack exchange,提问作者Андрей Бабкин

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 01:25:57