Spec-Zone.ru › Tokio

Структура JoinSet

pub struct JoinSet<T> { /* private fields */ }
Доступно только при включённой функции crate rt.

Коллекция задач, запущенных в среде выполнения Tokio.

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

Гарантии относительно идентификаторов задач

Пока задача отслеживается в JoinSet, её идентификатор уникален относительно идентификаторов всех остальных запущенных задач в Tokio. Для этой цели отслеживание задачи в JoinSet эквивалентно хранению JoinHandle для неё. Подробнее см. в документации по идентификатору задачи.

Реализации

impl<T> JoinSet<T>

pub fn new() -> Self

Создаёт новый JoinSet.

pub fn len(&self) -> usize

Возвращает количество задач, находящихся в JoinSet.

pub fn is_empty(&self) -> bool

Возвращает, пуст ли JoinSet.

impl<T: 'static> JoinSet<T>

pub fn build_task(&mut self) -> Builder<'_, T>

Доступно только на tokio_unstable и при включённой функции crate tracing.

Возвращает Builder, который можно использовать для настройки задачи перед её запуском в этом JoinSet.

Примеры
use tokio::task::JoinSet;

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let mut set = JoinSet::new();

    // Use the builder to configure a task's name before spawning it.
    set.build_task()
        .name("my_task")
        .spawn(async { /* ... */ })?;

    Ok(())
}

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

Запускает указанную задачу в JoinSet и возвращает AbortHandle, который можно использовать для удалённой отмены задачи.

Переданная future начнёт выполняться в фоновом режиме сразу после вызова этого метода, даже если вы не ожидаете ничего в этом JoinSet.

Паника

Этот метод вызывает панику, если его вызвать вне среды выполнения Tokio.

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

Запускает указанную задачу в предоставленной среде выполнения и сохраняет её в этом JoinSet, возвращая AbortHandle, который можно использовать для удалённой отмены задачи.

Переданная future начнёт выполняться в фоновом режиме сразу после вызова этого метода, даже если вы не ожидаете ничего в этом JoinSet.

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

Запускает указанную задачу в текущем LocalSet или LocalRuntime и сохраняет её в этом JoinSet, возвращая AbortHandle, который можно использовать для удалённой отмены задачи.

Переданная future начнёт выполняться в фоновом режиме сразу после вызова этого метода, даже если вы не ожидаете ничего в этом JoinSet.

Паника

Этот метод вызывает панику, если его вызвать вне LocalSet или LocalRuntime.

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.

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]);
    }
}
Паника

Этот метод вызывает панику, если его вызвать вне среды выполнения Tokio.

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

Запускает блокирующий код в пуле потоков для блокирующих задач указанной среды выполнения и сохраняет его в этом JoinSet, возвращая AbortHandle, который можно использовать для удалённой отмены задачи.

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

Ожидает завершения одной из задач в наборе и возвращает её результат.

Возвращает None, если набор пуст.

Безопасность при отмене

Этот метод безопасен при отмене. Если join_next используется в качестве ветви в tokio::select! и первой завершается другая ветвь, гарантируется, что из этого JoinSet не было удалено ни одной задачи.

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

Ожидает завершения одной из задач в наборе и возвращает её результат вместе с идентификатором задачи.

Возвращает None, если набор пуст.

Если этот метод возвращает ошибку, идентификатор завершившейся с ошибкой задачи можно получить с помощью метода JoinError::id.

Безопасность при отмене

Этот метод безопасен при отмене. Если join_next_with_id используется в качестве ветви в tokio::select! и первой завершается другая ветвь, гарантируется, что из этого JoinSet не было удалено ни одной задачи.

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

Пытается присоединиться к одной из завершившихся задач в наборе и вернуть её результат.

Возвращает None, если нет завершившихся задач или набор пуст.

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

Пытается присоединиться к одной из завершившихся задач в наборе и вернуть её результат вместе с идентификатором задачи.

Возвращает None, если нет завершившихся задач или набор пуст.

Если этот метод возвращает ошибку, идентификатор завершившейся с ошибкой задачи можно получить с помощью метода JoinError::id.

pub async fn shutdown(&mut self)

Прерывает все задачи и ожидает завершения их остановки.

Вызов этого метода эквивалентен вызову abort_all, а затем многократному вызову join_next, пока он не вернёт None.

Этот метод игнорирует любые паники в останавливаемых задачах. После возврата этого вызова JoinSet будет пуст.

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

Ожидает завершения всех задач в этом JoinSet и возвращает вектор их результатов.

Результаты будут сохранены в порядке завершения задач, а не в порядке их запуска. Это удобный метод, эквивалентный вызову join_next в цикле. Если какая-либо задача в JoinSet завершится с ошибкой JoinError, этот вызов join_all вызовет панику, а все оставшиеся задачи в 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_all с использованием join_next и цикла.

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

pub fn abort_all(&mut self)

Прерывает все задачи в этом JoinSet.

Этот метод не удаляет задачи из JoinSet. Чтобы дождаться завершения отмены задач, вызывайте join_next в цикле, пока JoinSet не опустеет.

pub fn detach_all(&mut self)

Удаляет все задачи из этого JoinSet, не прерывая их.

Задачи, удалённые этим вызовом, продолжат выполняться в фоновом режиме, даже если JoinSet будет удалён.

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

Проверяет, завершилась ли одна из задач в наборе.

Если этот метод возвращает Poll::Ready(Some(_)), завершившаяся задача удаляется из набора.

Когда метод возвращает Poll::Pending, Waker из переданного Context запланирован для пробуждения после завершения задачи в JoinSet. Обратите внимание: при нескольких вызовах poll_join_next пробуждение будет запланировано только для Waker из Context, переданного при последнем вызове.

Возвращает

Эта функция возвращает:

  • Poll::Pending, если JoinSet не пуст, но сейчас нет задачи с доступным результатом.
  • Poll::Ready(Some(Ok(value))), если одна из задач в этом JoinSet завершилась. value — это возвращаемое значение одной из завершившихся задач.
  • Poll::Ready(Some(Err(err))), если одна из задач в этом JoinSet вызвала панику или была прервана. err — это JoinError от задачи, вызвавшей панику или прерванной.
  • Poll::Ready(None), если JoinSet пуст.

Обратите внимание: этот метод может вернуть Poll::Pending, даже если одна из задач уже завершилась. Это может произойти при исчерпании бюджета кооперативного планировщика.

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

Проверяет, завершилась ли одна из задач в наборе.

Если этот метод возвращает Poll::Ready(Some(_)), завершившаяся задача удаляется из набора.

Когда метод возвращает Poll::Pending, Waker из переданного Context запланирован для пробуждения после завершения задачи в JoinSet. Обратите внимание: при нескольких вызовах poll_join_next пробуждение будет запланировано только для Waker из Context, переданного при последнем вызове.

Возвращает

Эта функция возвращает:

  • Poll::Pending, если JoinSet не пуст, но сейчас нет задачи с доступным результатом.
  • Poll::Ready(Some(Ok((id, value)))), если одна из задач в этом JoinSet завершилась. value — это возвращаемое значение одной из завершившихся задач, а id — это идентификатор задачи.
  • Poll::Ready(Some(Err(err))), если одна из задач в этом JoinSet вызвала панику или была прервана. err — это JoinError от задачи, вызвавшей панику или прерванной.
  • Poll::Ready(None), если JoinSet пуст.

Обратите внимание: этот метод может вернуть Poll::Pending, даже если одна из задач уже завершилась. Это может произойти при исчерпании бюджета кооперативного планировщика.

Реализации трейтов

impl<T> Debug for JoinSet<T>

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

Форматирует значение с помощью указанного форматтера. Подробнее

impl<T> Default for JoinSet<T>

fn default() -> Self

Возвращает «значение по умолчанию» для типа. Подробнее

impl<T> Drop for JoinSet<T>

fn drop(&mut self)

Выполняет деструктор для этого типа. Подробнее

fn pin_drop(self: Pin<&mut Self>)

🔬Это экспериментальный API, доступный только в nightly-версии. (pin_ergonomics)
Выполняет деструктор для этого типа, но, в отличие от Drop::drop, требует, чтобы self был закреплён. Подробнее

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

Дополняет JoinSet future-объектами из итератора.

Это эквивалентно вызову 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]);
    }
}

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

Дополняет коллекцию содержимым итератора. Подробнее

fn extend_one(&mut self, item: A)

🔬Это экспериментальный API, доступный только в nightly-версии. (extend_one)
Дополняет коллекцию ровно одним элементом.

fn extend_reserve(&mut self, additional: usize)

🔬Это экспериментальный API, доступный только в nightly-версии. (extend_one)
Резервирует в коллекции место для указанного количества дополнительных элементов. Подробнее

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

Собирает итератор фьючерсов в 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]);
}

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

Создаёт значение из итератора. Подробнее

Автоматические реализации трейтов

impl<T> !RefUnwindSafe for JoinSet<T>

impl<T> !UnwindSafe for JoinSet<T>

impl<T> Freeze 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> Any for T
where T: 'static + ?Sized,

fn type_id(&self) -> TypeId

Получает TypeId для self. Подробнее

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

fn borrow(&self) -> &T

Неизменяемо заимствует данные из принадлежащего значения. Подробнее

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

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

Изменяемо заимствует данные из принадлежащего значения. Подробнее

impl<T> From<T> for T

fn from(t: T) -> T

Возвращает аргумент без изменений.

impl<T> Instrument for T

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Инструментирует этот тип с помощью предоставленного Span и возвращает обёртку Instrumented. Подробнее

fn in_current_span(self) -> Instrumented<Self> ⓘ

Инструментирует этот тип с помощью текущего Span и возвращает обёртку Instrumented. Подробнее

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

fn into(self) -> U

Вызывает U::from(self).

То есть результат этого преобразования определяется тем, что выберет реализация From<T> for U.

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

type Error = Infallible

Тип, возвращаемый в случае ошибки преобразования.

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

Тип, возвращаемый в случае ошибки преобразования.

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

Выполняет преобразование.

impl<T> WithSubscriber for T

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Присоединяет предоставленный Subscriber к этому типу и возвращает обёртку WithDispatch. Подробнее

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Присоединяет текущий по умолчанию Subscriber к этому типу и возвращает обёртку WithDispatch. Подробнее

MIT License
Copyright © Tokio Contributors
https://docs.rs/tokio/1.53.1/tokio/task/struct.JoinSet.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API