gpt4 book ai didi

asynchronous - 异步任务中止时会发生什么?

转载 作者:行者123 更新时间:2023-12-03 11:24:48 27 4
gpt4 key购买 nike

rust 有 async可以绑定(bind)到 Abortable 的方法 future 。文档说,当中止时:

the future will complete immediately without making any further progress.



绑定(bind)到 future 的任务所拥有的变量会被丢弃吗?如果这些变量实现 drop , 将 drop叫做?如果 future 催生了其他的 future ,会不会全部被链式中止?

例如: In the following snippet ,我没有看到为中止的任务发生析构函数,但我不知道它是没有被调用还是发生在没有显示打印的单独线程中。
use futures::executor::block_on;
use futures::future::{AbortHandle, Abortable};

struct S {
i: i32,
}

impl Drop for S {
fn drop(&mut self) {
println!("dropping S");
}
}

async fn f() -> i32 {
let s = S { i: 42 };
std::thread::sleep(std::time::Duration::from_secs(2));
s.i
}

fn main() {
println!("first test...");
let (abort_handle, abort_registration) = AbortHandle::new_pair();
let _ = Abortable::new(f(), abort_registration);
abort_handle.abort();
std::thread::sleep(std::time::Duration::from_secs(1));

println!("second test...");
let (_, abort_registration) = AbortHandle::new_pair();
let task = Abortable::new(f(), abort_registration);
block_on(task).unwrap();
std::thread::sleep(std::time::Duration::from_secs(1));
}

playground

最佳答案

是的,已创建的值将被删除。

在您的第一个示例中,f 返回的 future 从未启动,所以 S永远不会被创建。这意味着它不能被丢弃。

在第二个示例中,该值被删除。

如果您既运行 future 又中止它,这一点会更加明显。在这里,我产生了两个并发 future :

  • 创建 S并等待 200 毫秒
  • 等待 100 毫秒并中止 future #1
  • use futures::future::{self, AbortHandle, Abortable};
    use std::time::Duration;
    use tokio::time;

    struct S {
    i: i32,
    }

    impl S {
    fn new(i: i32) -> Self {
    println!("Creating S {}", i);
    S { i }
    }
    }

    impl Drop for S {
    fn drop(&mut self) {
    println!("Dropping S {}", self.i);
    }
    }

    #[tokio::main]
    async fn main() {
    let create_s = async {
    let s = S::new(42);
    time::delay_for(Duration::from_millis(200)).await;
    println!("Creating {} done", s.i);
    };
    let (abort_handle, abort_registration) = AbortHandle::new_pair();
    let create_s = Abortable::new(create_s, abort_registration);

    let abort_s = async move {
    time::delay_for(Duration::from_millis(100)).await;
    abort_handle.abort();
    };

    let c = tokio::spawn(create_s);
    let a = tokio::spawn(abort_s);

    let (c, a) = future::join(c, a).await;

    println!("{:?}, {:?}", c, a);
    }

    Creating S 42
    Dropping S 42
    Ok(Err(Aborted)), Ok(())

    请注意,我已切换到 Tokio 以便能够使用 time::delay_for ,因为你不应该在异步函数中使用阻塞操作。

    也可以看看:
  • Why does Future::select choose the future with a longer sleep period first?
  • What is the best approach to encapsulate blocking I/O in future-rs?

  • If the future has spawned other futures, will all of them be aborted in a chain?



    不,当你 spawn一个 future ,它与它产生的地方是断开的。

    也可以看看:
  • What is the purpose of async/await in Rust?
  • 关于asynchronous - 异步任务中止时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59613782/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com