Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Функция spawn

Источник: Документация smol::spawn

#![allow(unused)]
fn main() {
pub fn spawn<T: Send + 'static>(
    future: impl Future<Output = T> + Send + 'static,
) -> Task<T>
}

Запускает задачу в глобальном исполнителе (по умолчанию однопоточном).

Описание

Существует глобальный исполнитель, который лениво инициализируется при первом использовании. Он включен в эту библиотеку для удобства при написании модульных тестов и небольших программ, но в остальных случаях более целесообразно создавать собственный Executor.

По умолчанию глобальный исполнитель запускается одним фоновым потоком, но вы также можете настроить количество потоков, установив переменную окружения SMOL_THREADS.

Поскольку исполнитель сохраняется навсегда, метод drop не вызывается для задач при выходе из программы.

Примеры

#![allow(unused)]
fn main() {
let task = smol::spawn(async {
    1 + 2
});

smol::block_on(async {
    assert_eq!(task.await, 3);
});
}

Особенности

Глобальный исполнитель

  • Ленивая инициализация: Создается при первом вызове spawn
  • Конфигурация потоков: Настраивается через переменную окружения SMOL_THREADS
  • Постоянное существование: Исполнитель не уничтожается при завершении программы

Требования к задачам

  • T: Send + 'static - результат должен быть передаваемым между потоками и иметь статическое время жизни
  • future: Send + 'static - фьючерс должен быть передаваемым и иметь статическое время жизни

Примеры использования

Базовая задача

#![allow(unused)]
fn main() {
use smol::{spawn, block_on};

let task = spawn(async {
    println!("Задача выполняется");
    42
});

let result = block_on(async {
    task.await
});
assert_eq!(result, 42);
}

Параллельные задачи

#![allow(unused)]
fn main() {
use smol::{spawn, block_on};

let task1 = spawn(async { 1 + 2 });
let task2 = spawn(async { 3 + 4 });

let (result1, result2) = block_on(async {
    (task1.await, task2.await)
});
assert_eq!(result1, 3);
assert_eq!(result2, 7);
}

Долгоиграющие задачи

#![allow(unused)]
fn main() {
use smol::{spawn, Timer};
use std::time::Duration;

let task = spawn(async {
    for i in 0..5 {
        println!("Итерация {}", i);
        Timer::after(Duration::from_secs(1)).await;
    }
    "Завершено"
});

// Задача продолжит выполняться в фоне даже без ожидания
}

Настройка через переменные окружения

# Запуск с 4 рабочими потоками
SMOL_THREADS=4 cargo run

# Запуск с 1 потоком (по умолчанию)
SMOL_THREADS=1 cargo run

Рекомендации по использованию

Когда использовать

  • Тестирование: Удобно для модульных тестов
  • Прототипирование: Быстрое создание прототипов
  • Небольшие программы: Простые приложения и утилиты

Когда не использовать

  • Производственные приложения: Лучше создавать собственный Executor
  • Специфичные требования: При необходимости тонкой настройки
  • Длительные процессы: Из-за особенностей управления временем жизни

Альтернативы

Для более сложных сценариев рекомендуется использовать:

#![allow(unused)]
fn main() {
use smol::Executor;

let executor = Executor::new();
let task = executor.spawn(async {
    // ваша задача
});
}

Безопасность

  • Send + 'static: Гарантирует безопасность между потоками
  • Глобальное состояние: Исполнитель существует всю жизнь программы
  • Автоматическое управление: Не требуется ручное уничтожение задач