异步任务中止后会发生什么? [英] What happens to an async task when it is aborted?

查看:76
本文介绍了异步任务中止后会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Rust具有 async 方法,这些方法可以绑定到

Rust has async methods that can be tied to Abortable futures. The documentation says that, when aborted:

未来将立即完成,而不会取得任何进一步的进展.

the future will complete immediately without making any further progress.

是否会删除与未来绑定的任务所拥有的变量?如果这些变量实现了 drop ,是否会调用 drop ?如果期货催生了其他期货,那么所有这些期货是否都会一连串中止?

Will the variables owned by the task bound to the future be dropped? If those variables implement drop, will drop be called? If the future has spawned other futures, will all of them be aborted in a chain?

例如:在以下代码段中,我没有看到析构函数发生在中止的任务上,但是我不知道它是不是被调用还是在单独的线程中发生了,在 print 没有显示.

E.g.: In the following snippet, I don't see the destructor happening for the aborted task, but I don't know if it is not called or happens in a separate thread where the print is not shown.

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));
}

游乐场

推荐答案

是的,将删除已创建的值.

在您的第一个示例中, f 返回的未来永远不会开始,因此永远不会创建 S .这意味着它不能被删除.

In your first example, the future returned by f is never started, so the S is never created. This means that it cannot be dropped.

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

In the second example, the value is dropped.

如果您同时运行将来的 并终止它,这将更加明显.在这里,我生成了两个并发的期货:

This is more obvious if you both run the future and abort it. Here, I spawn two concurrent futures:

  1. 创建一个 S 并等待200ms
  2. 等待100毫秒并中止将来的#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 ,因为您永远不要在异步函数中使用阻塞操作.

Note that I've switched to Tokio to be able to use time::delay_for, as you should never use blocking operations in an async function.

另请参阅:

如果期货催生了其他期货,它们是否都将被链中止?

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

否,当您生成未来时,它会与生成的地方断开连接.

No, when you spawn a future, it is disconnected from where it was spawned.

另请参阅:

这篇关于异步任务中止后会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆