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

使用tokio::select!等待多信号时遇临时值被借用释放错误

在Tokio中同时监听SIGINT与SIGTERM的正确实现

在Tokio项目中尝试同时监听SIGTERM和SIGINT信号时,单独监听单个信号可正常运行:

tracing::debug!("Waiting for the end of the world");
signal(SignalKind::terminate())?.recv().await;

但使用tokio::select!同时监听两个信号时,会触发临时值在被借用时被释放的编译错误:

错误代码

use tokio::signal::unix::{signal, SignalKind};
tokio::select! {
    _ = signal(SignalKind::interrupt())?.recv() => println!("SIGINT"),
    _ = signal(SignalKind::terminate())?.recv() => println!("SIGTERM"),
}
println!("terminating the process...");

编译错误信息

error[E0716]: temporary value dropped while borrowed
   --> src/main.rs:495:13
    |
494 |       let ans = tokio::select! {
    |  _______________-
495 | |         _ = signal(SignalKind::interrupt())?.recv() => println!("SIGINT"),
    | |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
496 | |         _ = signal(SignalKind::terminate())?.recv() => println!("SIGTERM"),
497 | |     };
    | |     -
    | |     |
    | |_____temporary value is freed at the end of this statement
    |       borrow might be used here, when `futures` is dropped and runs the destructor for type `(impl futures_util::Future<Output = std::option::Option<()>>, impl futures_util::Future<Output = std::option::Option<()>>)`

问题原因

signal()函数返回的Signal实例是临时值,recv()返回的Future会持有对该Signal的引用。当select!块执行结束时,临时Signal实例会被销毁,但Future可能仍在引用它,导致生命周期不匹配。

正确实现方式

提前创建并持有两个Signal实例,确保它们的生命周期覆盖整个select!执行过程:

use tokio::signal::unix::{signal, SignalKind};

// 提前创建信号监听器并持有所有权,延长生命周期
let mut sigint = signal(SignalKind::interrupt())?;
let mut sigterm = signal(SignalKind::terminate())?;

tokio::select! {
    _ = sigint.recv() => println!("SIGINT received"),
    _ = sigterm.recv() => println!("SIGTERM received"),
}

println!("terminating the process...");

说明

  • 将signal()返回的实例绑定到变量上,确保其生命周期足够长,直到select!执行完成
  • select!中调用recv()时,Future引用的是持久化的变量,不会出现临时值提前释放的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 01:10:28