跳到主要内容

JoinHandle

搜索

结构体 JoinHandle 

源代码
pub struct JoinHandle<T> { /* 私有字段 */ }
展开描述

用于加入任务(等待其终止)的所有权权限。

这可以看作是 Tokio 任务的 std::thread::JoinHandle 等价物,而不是线程的等价物。请注意,与此 JoinHandle 关联的后台任务在你调用 spawn 时立即开始运行,即使你尚未 await 此 JoinHandle

JoinHandle 被 drop 时,它会分离关联的任务,这意味着不再有该任务的句柄,也无法再 join 它。

structtask::spawntask::spawn_blocking 函数创建。

保证在通过 JoinHandle awaitJoinHandle::is_finishedAbortHandle::is_finished 观察到任务完成之前,已生成任务的析构函数已经运行完毕。

§取消安全性

&mut JoinHandle<T> 类型是取消安全的。如果在 tokio::select! 语句中将其用作事件,并且其他某个分支先完成,则可以保证任务的输出不会丢失。

如果 JoinHandle 被 drop,则任务将继续在后台运行,并且其返回值将丢失。

§示例

task::spawn 创建:

use tokio::task;

let join_handle: task::JoinHandle<_> = task::spawn(async {
    // some work here
});

task::spawn_blocking 创建:

use tokio::task;

let join_handle: task::JoinHandle<_> = task::spawn_blocking(|| {
    // some blocking work here
});

JoinHandle<T> 中的泛型参数 T 是已生成任务的返回类型。如果返回值是 i32,则 join handle 的类型为 JoinHandle<i32>

use tokio::task;

let join_handle: task::JoinHandle<i32> = task::spawn(async {
    5 + 3
});

如果任务没有返回值,则 join handle 的类型为 JoinHandle<()>

use tokio::task;

let join_handle: task::JoinHandle<()> = task::spawn(async {
    println!("I return nothing.");
});

请注意,handle.await 不会直接给出返回类型。它被包装在 Result 中,因为已生成任务中的 panic 会被 Tokio 捕获。必须双重链接 ? 运算符才能提取返回值:

use tokio::task;
use std::io;

let join_handle: task::JoinHandle<Result<i32, io::Error>> = tokio::spawn(async {
    Ok(5 + 3)
});

let result = join_handle.await??;
assert_eq!(result, 8);
Ok(())

如果任务发生 panic,则错误是包含该 panic 的 JoinError

use tokio::task;
use std::io;
use std::panic;

#[tokio::main]
async fn main() -> io::Result<()> {
    let join_handle: task::JoinHandle<Result<i32, io::Error>> = tokio::spawn(async {
        panic!("boom");
    });

    let err = join_handle.await.unwrap_err();
    assert!(err.is_panic());
    Ok(())
}

子任务被分离并比其父任务活得更久:

use tokio::task;
use tokio::time;
use std::time::Duration;

let original_task = task::spawn(async {
    let _detached_task = task::spawn(async {
        // Here we sleep to make sure that the first task returns before.
        time::sleep(Duration::from_millis(10)).await;
        // This will be called, even though the JoinHandle is dropped.
        println!("♫ Still alive ♫");
    });
});

original_task.await.expect("The task being joined has panicked");
println!("Original task is joined.");

// We make sure that the new task has time to run, before the main
// task returns.

time::sleep(Duration::from_millis(1000)).await;

实现§

源代码§

impl<T> JoinHandle<T>

源代码

pub fn abort(&self)

中止与该句柄关联的任务。

await 一个已取消的任务可能会像往常一样完成(如果任务在被取消时已经完成),但最有可能的是失败并返回已取消JoinError

请注意,使用 spawn_blocking 派生的任务无法被中止,因为它们不是异步的。如果对 spawn_blocking 任务调用 abort则不会产生任何效果,任务将继续正常运行。例外情况是任务尚未开始运行;此时调用 abort 可能会阻止任务启动。

有关取消的更多信息,另请参阅 模块级文档

use tokio::time;

let mut handles = Vec::new();

handles.push(tokio::spawn(async {
   time::sleep(time::Duration::from_secs(10)).await;
   true
}));

handles.push(tokio::spawn(async {
   time::sleep(time::Duration::from_secs(10)).await;
   false
}));

for handle in &handles {
    handle.abort();
}

for handle in handles {
    assert!(handle.await.unwrap_err().is_cancelled());
}
源代码

pub fn is_finished(&self) -> bool

检查与此 JoinHandle 关联的任务是否已完成。

请注意,即使已对任务调用 abort,此方法也可能返回 false。这是因为取消过程可能需要一些时间,并且此方法在取消完成之前不会返回 true

use tokio::time;

let handle1 = tokio::spawn(async {
    // do some stuff here
});
let handle2 = tokio::spawn(async {
    // do some other stuff here
    time::sleep(time::Duration::from_secs(10)).await;
});
// Wait for the task to finish
handle2.abort();
time::sleep(time::Duration::from_secs(1)).await;
assert!(handle1.is_finished());
assert!(handle2.is_finished());
源代码

pub fn abort_handle(&self) -> AbortHandle

返回一个新的 AbortHandle,可用于远程中止此任务。

await 由 AbortHandle 取消的任务,如果该任务在被取消时已经完成,则可能照常完成,但很可能以 已取消JoinError 失败。

use tokio::{time, task};

let mut handles = Vec::new();

handles.push(tokio::spawn(async {
   time::sleep(time::Duration::from_secs(10)).await;
   true
}));

handles.push(tokio::spawn(async {
   time::sleep(time::Duration::from_secs(10)).await;
   false
}));

let abort_handles: Vec<task::AbortHandle> = handles.iter().map(|h| h.abort_handle()).collect();

for handle in abort_handles {
    handle.abort();
}

for handle in handles {
    assert!(handle.await.unwrap_err().is_cancelled());
}
源代码

pub fn id(&self) -> Id

返回相对于其他当前已派生任务能唯一标识此任务的 任务 ID

trait 实现§

源代码§

impl<T> Debug for JoinHandle<T>
where T: Debug,

源代码§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result

使用给定的格式化器格式化此值。 更多信息
源代码§

impl<T> Drop for JoinHandle<T>

源代码§

fn drop(&mut self)

执行此类型的析构函数。 更多信息
源代码§

impl<T> Future for JoinHandle<T>

源代码§

type Output = Result<T, JoinError>

The type of value produced on completion.
源代码§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering the current task for wakeup if the value is not yet available. 更多信息
源代码§

impl<T> RefUnwindSafe for JoinHandle<T>

源代码§

impl<T: Send> Send for JoinHandle<T>

源代码§

impl<T: Send> Sync for JoinHandle<T>

源代码§

impl<T> Unpin for JoinHandle<T>

源代码§

impl<T> UnwindSafe for JoinHandle<T>

自动 trait 实现§

§

impl<T> Freeze for JoinHandle<T>

§

impl<T> UnsafeUnpin for JoinHandle<T>

blanket 实现§

源代码§

impl<T> Any for T
where T: 'static + ?Sized,

源代码§

fn type_id(&self) -> TypeId

Gets the TypeId of self. 更多信息
源代码§

impl<T> Borrow<T> for T
where T: ?Sized,

源代码§

fn borrow(&self) -> &T

Immutably borrows from an owned value. 更多信息
源代码§

impl<T> BorrowMut<T> for T
where T: ?Sized,

源代码§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. 更多信息
源代码§

impl<T> From<T> for T

源代码§

fn from(t: T) -> T

原样返回参数。

源代码§

impl<T, U> Into<U> for T
where U: From<T>,

源代码§

fn into(self) -> U

调用 U::from(self)

也就是说,此转换是 From<T> for U 实现选择执行的操作。

源代码§

impl<F> IntoFuture for F
where F: Future,

源代码§

type Output = <F as Future>::Output

The output that the future will produce on completion.
源代码§

type IntoFuture = F

Which kind of future are we turning this into?
源代码§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. 更多信息
源代码§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

源代码§

type Error = Infallible

The type returned in the event of a conversion error.
源代码§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

执行转换。
源代码§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

源代码§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
源代码§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

执行转换。