【发布时间】:2020-08-23 12:42:54
【问题描述】:
这就是我想要实现的目标
root> ./webserver start // Does not block the terminal after startup, runs in the background and the process is guarded
root>
我目前的实现逻辑:
后台运行的逻辑 use std::process::Command;
use std::thread;
use std::env;
use std::time::Duration;
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() == 2 {
if &args[1] == "start" {
// Main process start child process
let child = Command::new(&args[0])
.spawn().expect("Child process failed to start.");
println!("child pid: {}", child.id());
// Main process exit
}
} else {Is there any more elegant approach? Looking forward to your reply
// Main business logic
run webserver
}
}
这样,rust会在后台运行,不会阻塞终端,但rust在后台打印的信息仍然会显示在终端上,退出终端时会退出当前的rust程序
进程守护程序逻辑我的想法是监控系统的退出信号,不处理退出请求
SIGHUP 1 /* Hangup (POSIX). */
SIGINT 2 /* Interrupt (ANSI). */
SIGQUIT 3 /* Quit (POSIX). */
SIGTERM 15 /* Termination (ANSI). */
代码:
use signal_hook::{iterator::Signals, SIGHUP,SIGINT,SIGQUIT,SIGTERM};
use std::{thread, time::Duration};
pub fn process_daemon() {
let signals = match Signals::new(&[SIGHUP,SIGINT,SIGQUIT,SIGTERM]) {
Ok(t) => t,
Err(e) => panic!(e),
};Is there any more elegant approach? Looking forward to your reply
thread::spawn(move || {
for sig in signals.forever() {
println!("Received signal {:?}", sig);
}
});
thread::sleep(Duration::from_secs(2));
}
还有更优雅的方法吗?期待您的回复。
【问题讨论】:
-
如果您可以使用像
systemd这样的流程管理器,而不是尝试在代码中解决它。这比尝试自己处理fork或子进程要痛苦得多。 -
一个本身会将其视为守护进程的程序将立即被我的系统禁止。没有任何程序能做到这一点。
-
这似乎是你的 shell 的原生 job control 功能的任务。只需使用
&后缀(在与sh 兼容的shell 中)开始您的工作,它将作为后台作业运行,或者正常启动,然后按Control-Z 暂停该进程,然后使用@ 在后台恢复它987654330@。查看您的 shell 文档以了解其他作业控制工具。正如@Matthias247 建议的那样,对于比临时运行更多的“生产”任务,请使用适当的服务管理器。 -
daemon(3) 呢?