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

能否在Tokio优雅关闭实现中避免使用tokio::select!宏?

替代tokio::select!实现Axum优雅关闭的方案

当然有替代方案可以避免使用tokio::select!宏,以下是两种可行的实现方式:

方案一:使用futures::future::select组合子

借助futures crate中的select函数,可手动组合两个future并等待第一个完成的信号。需要先在Cargo.toml中添加futures依赖。

代码示例:

use tokio::signal;
use futures::future::{select, Either};

pub async fn shutdown_signal() {
    let ctrl_c = async {
        signal::ctrl_c()
            .await
            .expect("failed to install Ctrl+C handler");
    };

    #[cfg(unix)]
    let terminate = async {
        signal::unix::signal(signal::unix::SignalKind::terminate())
            .expect("failed to install signal handler")
            .recv()
            .await;
    };

    #[cfg(not(unix))]
    let terminate = std::future::pending::<()>();

    // 用futures::select替代tokio::select!
    match select(ctrl_c, terminate).await {
        Either::Left(_) => {}, // Ctrl+C信号触发
        Either::Right(_) => {}, // 终止信号触发
    }

    tracing::info!("signal received, starting graceful shutdown...");
}

方案二:将信号转为Stream后合并监听

利用tokio_stream crate将信号处理转为Stream,合并两个流后监听第一个到达的信号。需要添加tokio-stream依赖。

代码示例:

use tokio::signal;
use tokio_stream::{StreamExt, wrappers::SignalStream};

pub async fn shutdown_signal() {
    // 处理Ctrl+C信号流
    let ctrl_c_stream = SignalStream::new(
        signal::ctrl_c()
            .expect("failed to install Ctrl+C handler")
    );

    #[cfg(unix)]
    let terminate_stream = {
        let sig_term = signal::unix::signal(signal::unix::SignalKind::terminate())
            .expect("failed to install signal handler");
        SignalStream::new(sig_term)
    };

    #[cfg(not(unix))]
    let terminate_stream = tokio_stream::empty();

    // 合并两个流,等待第一个信号
    ctrl_c_stream.merge(terminate_stream).next().await;

    tracing::info!("signal received, starting graceful shutdown...");
}

注意事项

  • 两种方案都需要额外引入第三方crate(futures或tokio-stream),而原代码仅依赖tokio,需要权衡依赖复杂度。
  • tokio::select!本质是tokio提供的语法糖,在可读性和简洁性上更优,如果没有特殊限制,原方案其实是更合适的选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 14:30:38