跳到主要内容

JoinSet

搜索

结构体 JoinSet 

Source
pub struct JoinSet<T> { /* private fields */ }
展开描述

在 Tokio runtime 上生成的若干任务的集合。

JoinSet 可用于等待集合中部分或全部任务的完成。该集合是无序的,任务将按照完成的顺序返回。

所有任务必须具有相同的返回类型 T

JoinSet 被丢弃时,JoinSet 中的所有任务会立即被终止。

§示例

派生多个任务并等待它们完成。

use tokio::task::JoinSet;

let mut set = JoinSet::new();

for i in 0..10 {
    set.spawn(async move { i });
}

let mut seen = [false; 10];
while let Some(res) = set.join_next().await {
    let idx = res.unwrap();
    seen[idx] = true;
}

for i in 0..10 {
    assert!(seen[i]);
}

§Task ID guarantees

当一个任务被追踪到 JoinSet 中时,其 ID 在 Tokio 的所有其他运行任务中是唯一的。就此目的而言,将任务追踪到 JoinSet 中等价于持有该任务的 JoinHandle。有关更多信息,请参阅 task ID 文档。

实现§

Source§

impl<T> JoinSet<T>

Source

pub fn new() -> Self

创建一个新的 JoinSet

Source

pub fn len(&self) -> usize

返回当前 JoinSet 中的任务数量。

Source

pub fn is_empty(&self) -> bool

返回 JoinSet 是否为空。

Source§

impl<T: 'static> JoinSet<T>

Source

pub fn spawn<F>(&mut self, task: F) -> AbortHandle
where F: Future<Output = T> + Send + 'static, T: Send,

将提供的任务派生到 JoinSet 上,返回一个 AbortHandle,可用于远程取消该任务。

提供的 future 会在调用此方法时立即开始在后台运行,即使你没有在该 JoinSet 上 await 任何东西。

§Panics

如果在 Tokio runtime 之外调用此方法会 panic。

Source

pub fn spawn_on<F>(&mut self, task: F, handle: &Handle) -> AbortHandle
where F: Future<Output = T> + Send + 'static, T: Send,

将提供的任务派生到给定的 runtime 上并存储到此 JoinSet,返回一个 AbortHandle,可用于远程取消该任务。

提供的 future 会在调用此方法时立即开始在后台运行,即使你没有在该 JoinSet 上 await 任何东西。

Source

pub fn spawn_local<F>(&mut self, task: F) -> AbortHandle
where F: Future<Output = T> + 'static,

将提供的任务派生到当前 LocalSetLocalRuntime 上并存储到此 JoinSet,返回一个 AbortHandle,可用于远程取消该任务。

提供的 future 会在调用此方法时立即开始在后台运行,即使你没有在该 JoinSet 上 await 任何东西。

§Panics

如果在 LocalSetLocalRuntime 之外调用此方法会 panic。

Source

pub fn spawn_local_on<F>( &mut self, task: F, local_set: &LocalSet, ) -> AbortHandle
where F: Future<Output = T> + 'static,

将提供的任务派生到给定的 LocalSet 上并存储到此 JoinSet,返回一个 AbortHandle,可用于远程取消该任务。

spawn_local 方法不同,此方法可用于在当前没有运行的 LocalSet 上派生本地任务。提供的 future 将在 LocalSet 下次启动时开始运行。

Source

pub fn spawn_blocking<F>(&mut self, f: F) -> AbortHandle
where F: FnOnce() -> T + Send + 'static, T: Send,

将阻塞代码派生到阻塞线程池并存储到此 JoinSet,返回一个 AbortHandle,可用于远程取消该任务。

§示例

派生多个阻塞任务并等待它们完成。

use tokio::task::JoinSet;

#[tokio::main]
async fn main() {
    let mut set = JoinSet::new();

    for i in 0..10 {
        set.spawn_blocking(move || { i });
    }

    let mut seen = [false; 10];
    while let Some(res) = set.join_next().await {
        let idx = res.unwrap();
        seen[idx] = true;
    }

    for i in 0..10 {
        assert!(seen[i]);
    }
}
§Panics

如果在 Tokio runtime 之外调用此方法会 panic。

Source

pub fn spawn_blocking_on<F>(&mut self, f: F, handle: &Handle) -> AbortHandle
where F: FnOnce() -> T + Send + 'static, T: Send,

将阻塞代码派生到给定 runtime 的阻塞线程池上并存储到此 JoinSet,返回一个 AbortHandle,可用于远程取消该任务。

Source

pub async fn join_next(&mut self) -> Option<Result<T, JoinError>>

等待集合中的某个任务完成,并返回其输出。

如果集合为空则返回 None

§Cancel Safety

此方法是 cancel safe 的。如果 join_nexttokio::select! 语句中作为事件且其他分支先完成,可以保证不会有任务从此 JoinSet 中被移除。

Source

pub async fn join_next_with_id(&mut self) -> Option<Result<(Id, T), JoinError>>

等待集合中的某个任务完成,并返回其输出以及完成任务对应的 task ID

如果集合为空则返回 None

当此方法返回错误时,可通过 JoinError::id 方法访问失败任务的 ID。

§Cancel Safety

此方法是 cancel safe 的。如果 join_next_with_idtokio::select! 语句中作为事件且其他分支先完成,可以保证不会有任务从此 JoinSet 中被移除。

Source

pub fn try_join_next(&mut self) -> Option<Result<T, JoinError>>

尝试加入集合中已完成的任务之一,并返回其输出。

如果没有已完成的任务,或集合为空,则返回 None

Source

pub fn try_join_next_with_id(&mut self) -> Option<Result<(Id, T), JoinError>>

尝试加入集合中已完成的任务之一,返回其输出以及完成任务对应的 task ID

如果没有已完成的任务,或集合为空,则返回 None

当此方法返回错误时,可通过 JoinError::id 方法访问失败任务的 ID。

Source

pub async fn shutdown(&mut self)

终止所有任务,并等待它们完成关闭。

调用此方法等价于先调用 abort_all,然后循环调用 join_next 直到它返回 None

此方法会忽略正在关闭的任务中的任何 panic。当此调用返回时,JoinSet 将为空。

Source

pub async fn join_all(self) -> Vec<T>

等待此 JoinSet 中所有任务完成,返回一个包含其结果的 vector。

结果将按照任务完成的顺序(而非派生的顺序)存储。这是一个便捷方法,等价于循环调用 join_next。如果 JoinSet 上的任何任务因 JoinError 而失败,那么对 join_all 的此次调用将 panic,并且 JoinSet 上所有剩余的任务都将被取消。若要以其他方式处理错误,请手动循环调用 join_next

§示例

派生多个任务并对它们调用 join_all

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

let mut set = JoinSet::new();

for i in 0..3 {
    set.spawn(async move {
        tokio::time::sleep(Duration::from_secs(3 - i)).await;
        i
    });
}

let output = set.join_all().await;
assert_eq!(output, vec![2, 1, 0]);

使用 join_next 和循环实现等效的 join_all

use tokio::task::JoinSet;
use std::panic;

let mut set = JoinSet::new();

for i in 0..3 {
    set.spawn(async move {i});
}

let mut output = Vec::new();
while let Some(res) = set.join_next().await{
    match res {
        Ok(t) => output.push(t),
        Err(err) if err.is_panic() => panic::resume_unwind(err.into_panic()),
        Err(err) => panic!("{err}"),
    }
}
assert_eq!(output.len(),3);
Source

pub fn abort_all(&mut self)

终止此 JoinSet 上的所有任务。

这不会从 JoinSet 中移除任务。要等待任务完成取消,你应该循环调用 join_next,直到 JoinSet 为空。

Source

pub fn detach_all(&mut self)

JoinSet 中移除所有任务而不终止它们。

被此调用移除的任务将在后台继续运行,即使 JoinSet 被丢弃。

Source

pub fn poll_join_next( &mut self, cx: &mut Context<'_>, ) -> Poll<Option<Result<T, JoinError>>>

轮询集合中是否有任务完成。

如果返回 Poll::Ready(Some(_)),则已完成的任务将从集合中移除。

当方法返回 Poll::Pending 时,提供的 Context 中的 Waker 将被调度以在 JoinSet 中的任务完成时接收 wakeup。请注意,多次调用 poll_join_next 时,只有最近一次调用所传入 Context 中的 Waker 会被调度接收 wakeup。

§Returns

此函数返回:

  • Poll::Pending if the JoinSet is not empty but there is no task whose output is available right now.
  • Poll::Ready(Some(Ok(value))) if one of the tasks in this JoinSet has completed. The value is the return value of one of the tasks that completed.
  • Poll::Ready(Some(Err(err))) if one of the tasks in this JoinSet has panicked or been aborted. The err is the JoinError from the panicked/aborted task.
  • Poll::Ready(None) if the JoinSet is empty.

请注意,即使已有任务完成,此方法也可能返回 Poll::Pending。当达到 协作预算 上限时,就会发生这种情况。

Source

pub fn poll_join_next_with_id( &mut self, cx: &mut Context<'_>, ) -> Poll<Option<Result<(Id, T), JoinError>>>

轮询集合中是否有任务完成。

如果返回 Poll::Ready(Some(_)),则已完成的任务将从集合中移除。

当方法返回 Poll::Pending 时,提供的 Context 中的 Waker 将被调度以在 JoinSet 中的任务完成时接收 wakeup。请注意,多次调用 poll_join_next 时,只有最近一次调用所传入 Context 中的 Waker 会被调度接收 wakeup。

§Returns

此函数返回:

  • Poll::Pending if the JoinSet is not empty but there is no task whose output is available right now.
  • Poll::Ready(Some(Ok((id, value)))) if one of the tasks in this JoinSet has completed. The value is the return value of one of the tasks that completed, and id is the task ID of that task.
  • Poll::Ready(Some(Err(err))) if one of the tasks in this JoinSet has panicked or been aborted. The err is the JoinError from the panicked/aborted task.
  • Poll::Ready(None) if the JoinSet is empty.

请注意,即使已有任务完成,此方法也可能返回 Poll::Pending。当达到 协作预算 上限时,就会发生这种情况。

Trait 实现§

Source§

impl<T> Debug for JoinSet<T>

Source§

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

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

impl<T> Default for JoinSet<T>

Source§

fn default() -> Self

Returns the “default value” for a type. 更多信息
Source§

impl<T> Drop for JoinSet<T>

Source§

fn drop(&mut self)

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

impl<T, F> Extend<F> for JoinSet<T>
where F: Future<Output = T> + Send + 'static, T: Send + 'static,

使用来自迭代器的 future 扩展 JoinSet

这等效于对迭代器中的每个元素调用 JoinSet::spawn

§示例

use tokio::task::JoinSet;

#[tokio::main]
async fn main() {
    let mut set: JoinSet<_> = (0..5).map(|i| async move { i }).collect();

    set.extend((5..10).map(|i| async move { i }));

    let mut seen = [false; 10];
    while let Some(res) = set.join_next().await {
        let idx = res.unwrap();
        seen[idx] = true;
    }

    for i in 0..10 {
        assert!(seen[i]);
    }
}
Source§

fn extend<I>(&mut self, iter: I)
where I: IntoIterator<Item = F>,

Extends a collection with the contents of an iterator. 更多信息
Source§

fn extend_one(&mut self, item: A)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
Source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. 更多信息
Source§

impl<T, F> FromIterator<F> for JoinSet<T>
where F: Future<Output = T> + Send + 'static, T: Send + 'static,

将 future 迭代器收集到 JoinSet 中。

这等效于对迭代器中的每个元素调用 JoinSet::spawn

§示例

JoinSet 文档中的主要示例也可以使用 collect 来编写:

use tokio::task::JoinSet;

let mut set: JoinSet<_> = (0..10).map(|i| async move { i }).collect();

let mut seen = [false; 10];
while let Some(res) = set.join_next().await {
    let idx = res.unwrap();
    seen[idx] = true;
}

for i in 0..10 {
     assert!(seen[i]);
}
Source§

fn from_iter<I: IntoIterator<Item = F>>(iter: I) -> Self

Creates a value from an iterator. 更多信息

自动 Trait 实现§

§

impl<T> Freeze for JoinSet<T>

§

impl<T> !RefUnwindSafe for JoinSet<T>

§

impl<T> Send for JoinSet<T>
where T: Send,

§

impl<T> Sync for JoinSet<T>
where T: Send,

§

impl<T> Unpin for JoinSet<T>

§

impl<T> UnsafeUnpin for JoinSet<T>

§

impl<T> !UnwindSafe for JoinSet<T>

Blanket 实现§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. 更多信息
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. 更多信息
Source§

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

Source§

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

Mutably borrows from an owned value. 更多信息
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

原样返回传入的参数。

Source§

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

Source§

fn into(self) -> U

调用 U::from(self)

也就是说,此转换的具体行为取决于 From<T> for U 的实现方式。

Source§

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

Source§

type Error = Infallible

转换出错时返回的类型。
Source§

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

执行转换。
Source§

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

Source§

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

转换出错时返回的类型。
Source§

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

执行转换。