【问题标题】:Is There any Thread Spawn with Timeout?是否有任何线程产生超时?
【发布时间】:2022-10-05 01:32:37
【问题描述】:

我想分叉/运行两个线程,每个线程都应该做一些工作(比如调用 REST API)。但是,如果尚未返回,我希望它们在达到某个超时阈值时停止/中断。

目前,我正在使用tokio::spawn(),但仍然无法生成这样的代码。尽管任何关键字都会受到赞赏,但代码 sn-p 会更有价值。

【问题讨论】:

  • 您可能希望将 stop-after-timeout-period-expired 逻辑添加到线程本身,以便线程自动退出。从外部停止线程意味着线程将没有机会清理它可能分配的任何资源,这可能会导致资源泄漏和/或死锁(如果线程在停止运行时锁定了一个或多个互斥锁) )
  • 谢谢@JeremyFriesner,正确的推理。我在想是否存在类似 tokio::timedout_spawn 的东西。
  • 可以将任务变成异步函数/未来,还是必须是在线程上运行的同步函数?如果它可以变成未来,那么您可以将其包装在timeout 中。
  • @cdhowie,哦,哇,我没想到超时也会与 spawn 一起使用。我会试一试。
  • @Jaafar它会工作,但一旦发生超时它就不会中止任务;任务将运行完成,但永远不会观察到结果。

标签: multithreading rust rust-tokio


【解决方案1】:

如果您的任务是异步的,您可以简单地将它们包装在 tokio::time::timeout 中,如果时间限制已过,这将缩短对 Future 的评估:

use std::time::Duration;
use tokio::time::timeout;

async fn task_one() { /* do good work */ }
async fn task_two() { /* do good work */ }

#[tokio::main]
async fn main() {
    let timelimit = Duration::from_secs(5);
    tokio::spawn(timeout(timelimit, task_one()));
    tokio::spawn(timeout(timelimit, task_two()));
}

如果您等待结果,如果在分配的时间内完成,他们将返回Results 和Ok(_),如果超出限制,则返回Err(Elapsed)

请记住,Future-cancellation 仅影响已取消的Future 的直接执行,并且不会取消任何间接/衍生的任务。例如,如果您像 timeout(timelimit, tokio::spawn(task_one())) 这样反转上面的调用,那么超时可能会超过,您不能再等待任务,但它会在后台继续,因为您只取消了等待的 JoinHandle结果从任务。

【讨论】:

    【解决方案2】:

    只需使用选择!宏。更多详情请参考官方Rust Async Book

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-28
      • 2021-06-25
      • 1970-01-01
      • 2020-03-08
      • 1970-01-01
      • 2017-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多