Структура Runtime
pub struct Runtime { /* private fields */ }
rt.Среда выполнения Tokio.
Среда выполнения предоставляет драйвер ввода-вывода, планировщик задач, таймер и пул блокирующих операций, необходимые для выполнения асинхронных задач.
Экземпляры Runtime можно создать с помощью new или Builder. Однако большинство пользователей вместо этого используют аннотацию #[tokio::main] для точки входа.
Подробнее см. в документации на уровне модуля.
Завершение работы
Завершить работу среды выполнения можно, удалив значение или вызвав shutdown_background либо shutdown_timeout.
Задачи, запущенные через Runtime::spawn, продолжают выполняться, пока не уступят управление. После этого они удаляются. Нет гарантии, что они выполнятся до конца, но это возможно, если они не уступят управление до завершения.
Блокирующие функции, запущенные через Runtime::spawn_blocking, продолжают выполняться до возврата.
Поток, инициирующий завершение работы, блокируется до остановки всех запущенных задач. Это может занять неопределённое время. Реализация Drop ожидает этого бесконечно.
Если бесконечное ожидание нежелательно, можно использовать методы shutdown_background и shutdown_timeout. По истечении времени ожидания запущенные задачи, которые не успели остановиться, и выполняющие их потоки остаются без управления. Задачи продолжают выполняться до наступления одного из условий остановки, но поток, инициирующий завершение работы, разблокируется.
После удаления среды выполнения все привязанные к ней ресурсы ввода-вывода перестают работать. Любой вызов их методов приведёт к ошибке.
Совместное использование
Есть несколько способов получить совместный доступ к среде выполнения Tokio:
Использование Arc<Runtime> или Handle позволяет выполнять различные действия со средой выполнения, например запускать новые задачи или входить в её контекст. Оба типа можно клонировать, чтобы создать новый дескриптор, предоставляющий доступ к той же среде выполнения. Передавая клоны разным задачам или потокам, вы сможете обращаться к среде выполнения из этих задач или потоков.
Разница между Arc<Runtime> и Handle заключается в том, что Arc<Runtime> не позволяет завершить работу среды выполнения, тогда как Handle этого не делает. Это связано с тем, что завершение работы среды выполнения происходит при вызове деструктора объекта Runtime.
Для вызова shutdown_background и shutdown_timeout требуется исключительное владение типом Runtime. При использовании Arc<Runtime> этого можно добиться с помощью Arc::try_unwrap, если осталась только одна сильная ссылка.
Войти в контекст среды выполнения можно с помощью методов Runtime::enter или Handle::enter. Они используют переменную локального хранилища потока для сохранения текущей среды выполнения. Находясь в контексте среды выполнения, вы будете вызывать такие методы, как tokio::spawn, которые используют среду выполнения, в чей контекст вы вошли.
Реализации
impl Runtime
pub fn new() -> Result<Runtime>
rt-multi-thread.Создаёт новый экземпляр среды выполнения со значениями конфигурации по умолчанию.
При этом инициализируются многопоточный планировщик, драйвер ввода-вывода и драйвер времени.
Большинству приложений не нужно вызывать эту функцию напрямую. Вместо этого они используют атрибут #[tokio::main]. Если требуется более сложная конфигурация, можно использовать построитель среды выполнения.
Подробнее см. в документации модуля.
Примеры
Создание нового Runtime со значениями конфигурации по умолчанию.
use tokio::runtime::Runtime;
let rt = Runtime::new()
.unwrap();
// Use the runtime...pub fn handle(&self) -> &Handle
Возвращает дескриптор механизма запуска задач среды выполнения.
Возвращённый дескриптор можно использовать для запуска задач в этой среде выполнения, а также клонировать, чтобы передавать Handle в другие потоки.
Вызов Handle::block_on для дескриптора многопоточной среды выполнения current_thread может привести к ошибкам. Подробнее см. в документации к Handle::block_on.
Примеры
use tokio::runtime::Runtime;
let rt = Runtime::new()
.unwrap();
let handle = rt.handle();
// Use the handle...pub fn spawn<F>(&self, future: F) -> JoinHandle<F::Output> ⓘ
Запускает фьючер в среде выполнения Tokio.
Переданный фьючер запускается исполнителем среды выполнения, обычно пулом потоков. Затем пул потоков отвечает за опрос фьючера до его завершения.
Переданный фьючер начнёт выполняться в фоновом режиме сразу после вызова spawn, даже если вы не ожидаете возвращённый JoinHandle (при условии, что среда выполнения работает).
Подробнее см. в документации модуля.
Примеры
use tokio::runtime::Runtime;
// Create the runtime
let rt = Runtime::new().unwrap();
// Spawn a future onto the runtime
rt.spawn(async {
println!("now running on a worker thread");
});pub fn spawn_blocking<F, R>(&self, func: F) -> JoinHandle<R> ⓘ
Выполняет переданную функцию в исполнителе, предназначенном для блокирующих операций.
Примеры
use tokio::runtime::Runtime;
// Create the runtime
let rt = Runtime::new().unwrap();
// Spawn a blocking function onto the runtime
rt.spawn_blocking(|| {
println!("now running on a worker thread");
});pub fn block_on<F: Future>(&self, future: F) -> F::Output
Выполняет фьючер до завершения в среде выполнения Tokio. Это точка входа в среду выполнения.
Переданный фьючер выполняется в текущем потоке, который блокируется до его завершения, после чего возвращается полученный результат. Все задачи и таймеры, которые фьючер запускает внутри себя, будут выполняться в среде выполнения.
Фьючер, не являющийся рабочей задачей
Обратите внимание, что фьючер, передаваемый этой функции, не выполняется как рабочая задача. Предполагается, что этот фьючер будет запускать другие задачи. Ожидание других фьючеров внутри переданного сюда фьючера будет выполняться не так быстро, как ожидание задач, запущенных в качестве рабочих.
Многопоточный планировщик
При использовании многопоточного планировщика фьючеры смогут выполняться в контексте драйвера ввода-вывода и таймера всей среды выполнения.
Все запущенные задачи продолжат выполняться после возврата block_on.
Однопоточный планировщик
Если включён однопоточный планировщик, block_on можно вызывать одновременно из нескольких потоков. Первый вызов получит во владение драйверы ввода-вывода и таймера. Это означает, что другие потоки, не владеющие драйверами, будут использовать их через этот поток. Когда первый вызов block_on завершится, другие потоки смогут «перехватить» драйвер, чтобы продолжить выполнение своих фьючеров.
Все запущенные задачи будут приостановлены после возврата block_on. Повторный вызов block_on возобновит ранее запущенные задачи.
Паника
Эта функция вызывает панику, если переданный фьючер вызывает панику или если функция вызвана в контексте асинхронного выполнения.
Примеры
use tokio::runtime::Runtime;
// Create the runtime
let rt = Runtime::new().unwrap();
// Execute the future, blocking the current thread until completion
rt.block_on(async {
println!("hello");
});pub fn enter(&self) -> EnterGuard<'_>
Входит в контекст среды выполнения.
Это позволяет создавать типы, которым при создании необходим доступный исполнитель, например Sleep или TcpStream. Это также позволит вызывать такие методы, как tokio::spawn.
Пример
use tokio::runtime::Runtime;
use tokio::task::JoinHandle;
fn function_that_spawns(msg: String) -> JoinHandle<()> {
// Had we not used `rt.enter` below, this would panic.
tokio::spawn(async move {
println!("{}", msg);
})
}
fn main() {
let rt = Runtime::new().unwrap();
let s = "Hello World!".to_string();
// By entering the context, we tie `tokio::spawn` to this executor.
let _guard = rt.enter();
let handle = function_that_spawns(s);
// Wait for the task before we end the test.
rt.block_on(handle).unwrap();
}pub fn shutdown_timeout(self, duration: Duration)
Завершает работу среды выполнения, ожидая не более duration, пока все запущенные задачи не остановятся.
Дополнительные сведения см. в документации на уровне структуры.
Примеры
use tokio::runtime::Runtime;
use tokio::task;
use std::thread;
use std::time::Duration;
fn main() {
let runtime = Runtime::new().unwrap();
runtime.block_on(async move {
task::spawn_blocking(move || {
thread::sleep(Duration::from_secs(10_000));
});
});
runtime.shutdown_timeout(Duration::from_millis(100));
}pub fn shutdown_background(self)
Завершает работу среды выполнения, не ожидая остановки запущенных задач.
Это может быть полезно, если нужно удалить среду выполнения из другой среды выполнения. Обычно удаление среды выполнения бесконечно блокирует выполнение до завершения запущенных блокирующих задач, что, как правило, недопустимо в асинхронном контексте. Вызвав shutdown_background(), можно удалить среду выполнения из такого контекста.
Однако следует учитывать, что, поскольку мы не ожидаем завершения блокирующих задач, это может привести к утечке ресурсов (любые блокирующие задачи продолжат выполняться до своего завершения).
Дополнительные сведения см. в документации на уровне структуры.
Эта функция эквивалентна вызову shutdown_timeout(Duration::from_nanos(0)).
use tokio::runtime::Runtime;
fn main() {
let runtime = Runtime::new().unwrap();
runtime.block_on(async move {
let inner_runtime = Runtime::new().unwrap();
// ...
inner_runtime.shutdown_background();
});
}pub fn metrics(&self) -> RuntimeMetrics
Возвращает представление, позволяющее получить сведения о производительности среды выполнения.
Реализации трейтов
impl RefUnwindSafe for Runtime
impl UnwindSafe for Runtime
Автоматические реализации трейтов
impl !Freeze for Runtime
impl Send for Runtime
impl Sync for Runtime
impl Unpin for Runtime
impl UnsafeUnpin for Runtime
Общие реализации
impl<T> BorrowMut<T> for Twhere T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
impl<T> Instrument for T
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
impl<T> WithSubscriber for T
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ
Subscriber к этому типу и возвращает обёртку WithDispatch. Подробнее
MIT License
Copyright © Tokio Contributors
https://docs.rs/tokio/1.53.1/tokio/runtime/struct.Runtime.html