【问题标题】:How to catch signals in Rust如何在 Rust 中捕获信号
【发布时间】:2022-01-17 00:27:22
【问题描述】:

我正在尝试编写一些代码来捕捉像 SIGTERM 这样的信号。

我找到了this,我还找到了How to handle blocking i/o in Rust, or long running external function calls in general

但在当前的 Rust 版本(每晚 0.12)中,std::io::signal::Listener 似乎已被删除。是不是放到别的地方了?如果是这样,有人可以指点我如何捕捉信号吗?

【问题讨论】:

标签: rust


【解决方案1】:

现在实现这一点似乎相当简单。 Rust 中的命令行应用程序的 Signal handling section 回顾了这个概念,并提到了处理特定信号的 ctrlc crate,以及处理一般信号的 signal-hook crate。

通过指南,使用信号挂钩应该很简单:

use std::{error::Error, thread};
use signal_hook::{iterator::Signals, SIGTERM};

fn main() -> Result<(), Box<Error>> {
    let signals = Signals::new(&[SIGTERM])?;

    thread::spawn(move || {
        for sig in signals.forever() {
            println!("Received signal {:?}", sig);
        }
    });

    Ok(())
}

【讨论】:

    【解决方案2】:

    我相信 std::io::signal 模块已在 this 拉取请求中删除。据称,对于本机运行时从未正确实现正确的信号处理,因此您现在可能无论如何都无法使用它。 This 似乎是这个问题的跟踪问题。

    与此同时,我认为,您将不得不从libc 降级到最低级别的不安全函数。

    【讨论】:

      【解决方案3】:

      在写这个答案的时候,有an RFC for built-in signals

      我使用the chan-signal crate取得了一些成功:

      #[macro_use]
      extern crate chan;
      extern crate chan_signal;
      
      use chan_signal::Signal;
      
      fn main() {
          // Signal gets a value when the OS sent a INT or TERM signal.
          let signal = chan_signal::notify(&[Signal::INT, Signal::TERM]);
          // When our work is complete, send a sentinel value on `sdone`.
          let (sdone, rdone) = chan::sync(0);
          // Run work.
          ::std::thread::spawn(move || run(sdone));
      
          // Wait for a signal or for work to be done.
          chan_select! {
              signal.recv() -> signal => {
                  println!("received signal: {:?}", signal)
              },
              rdone.recv() => {
                  println!("Program completed normally.");
              }
          }
      }
      
      fn run(_sdone: chan::Sender<()>) {
          println!("Running work for 5 seconds.");
          println!("Can you send a signal quickly enough?");
          // Do some work.
          ::std::thread::sleep_ms(5000);
      
          // _sdone gets dropped which closes the channel and causes `rdone`
          // to unblock.
      }
      

      【讨论】:

      • 虽然这个答案在发布时是有效的,但 chan-signal crate 确实在几年前达到了它的生命周期,并被其作者认为已弃用。跨度>
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-06-10
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多