Модуль time
Доступно только с флагом функции time.
Утилиты для отслеживания времени.
Этот модуль предоставляет ряд типов для выполнения кода по истечении заданного периода времени.
-
Sleep- это future, который не выполняет работы и завершается в определенный момент времениInstant. -
Interval- это поток, выдающий значение с фиксированным периодом. Он инициализируетсяDurationи повторно выдает значение каждый раз, когда длительность истекает. -
Timeout- оборачивает future или поток, устанавливая верхнюю границу времени, которое ему разрешено выполняться. Если future или поток не завершается вовремя, он отменяется и возвращается ошибка.
Этих типов достаточно для обработки большого количества сценариев, связанных со временем.
Эти типы должны использоваться в контексте Runtime.
Примеры
Ожидание 100 мс и вывод сообщения
#![allow(unused)] fn main() { use std::time::Duration; use tokio::time::sleep; sleep(Duration::from_millis(100)).await; println!("100 мс прошло"); }
Требование, чтобы операция занимала не более 1 секунды
#![allow(unused)] fn main() { use tokio::time::{timeout, Duration}; async fn long_future() { // выполняем работу здесь } let res = timeout(Duration::from_secs(1), long_future()).await; if res.is_err() { println!("операция превысила время ожидания"); } }
Простой пример использования interval для выполнения задачи каждые две секунды
Разница между interval и sleep заключается в том, что interval измеряет время с последнего тика, что означает, что .tick().await может ждать меньше времени, чем указанная для интервала длительность, если между вызовами .tick().await прошло некоторое время.
Если в примере ниже заменить tick на sleep, задача будет выполняться только раз в три секунды, а не каждые две секунды.
#![allow(unused)] fn main() { use tokio::time; async fn task_that_takes_a_second() { println!("hello"); time::sleep(time::Duration::from_secs(1)).await } let mut interval = time::interval(time::Duration::from_secs(2)); for _i in 0..5 { interval.tick().await; task_that_takes_a_second().await; } }
Использование таймаута с потоком
#![allow(unused)] fn main() { use tokio::time::{timeout, Duration}; use tokio_stream::{self as stream, StreamExt}; let mut stream = stream::iter(1..=10); let result = timeout(Duration::from_secs(1), async move { while let Some(value) = stream.next().await { println!("обрабатываем значение: {}", value); // Имитация работы tokio::time::sleep(Duration::from_millis(200)).await; } }).await; match result { Ok(_) => println!("поток завершился успешно"), Err(_) => println!("поток превысил время ожидания"), } }
Использование sleep_until для планирования на определенное время
#![allow(unused)] fn main() { use tokio::time::{sleep_until, Instant}; use std::time::Duration; // Запланировать выполнение через 5 секунд от текущего момента let deadline = Instant::now() + Duration::from_secs(5); sleep_until(deadline).await; println!("5 секунд прошло с момента планирования"); }
Реэкспорт
#![allow(unused)] fn main() { pub use std::time::Duration; }
Модули
| Имя | Флаги | Описание |
|---|---|---|
error | Типы ошибок времени. |
Структуры
| Имя | Описание |
|---|---|
Instant | Измерение монотонно неубывающих часов. Непрозрачно и полезно только с Duration. |
Interval | Интервал, возвращаемый interval и interval_at. |
Sleep | Future, возвращаемый sleep и sleep_until. |
Timeout | Future, возвращаемый timeout и timeout_at. |
Перечисления
| Имя | Описание |
|---|---|
MissedTickBehavior | Определяет поведение Interval при пропуске тика. |
Функции
| Имя | Флаги | Описание |
|---|---|---|
advance | test-util | Перемещает время вперед. |
interval | Создает новый Interval, который выдает значения с интервалом period. Первый тик завершается немедленно. Поведение по умолчанию для пропущенных тиков - Burst, но это можно настроить, вызвав set_missed_tick_behavior. | |
interval_at | Создает новый Interval, который выдает значения с интервалом period, причем первый тик завершается в start. Поведение по умолчанию для пропущенных тиков - Burst, но это можно настроить, вызвав set_missed_tick_behavior. | |
pause | test-util | Приостанавливает время. |
resume | test-util | Возобновляет время. |
sleep | Ожидает, пока не пройдет указанная длительность. | |
sleep_until | Ожидает, пока не будет достигнут указанный крайний срок. | |
timeout | Требует, чтобы Future завершился до истечения указанной длительности. | |
timeout_at | Требует, чтобы Future завершился до указанного момента времени. |
Дополнительные примеры
Настройка поведения при пропущенных тиках
#![allow(unused)] fn main() { use tokio::time::{interval, Duration, MissedTickBehavior}; let mut interval = interval(Duration::from_secs(1)); interval.set_missed_tick_behavior(MissedTickBehavior::Skip); loop { interval.tick().await; println!("тик"); // Если эта задача занимает больше 1 секунды, следующие тики будут пропущены // до следующего подходящего момента времени } }
Комбинирование нескольких таймеров
#![allow(unused)] fn main() { use tokio::time::{sleep, timeout, Duration}; async fn complex_operation() -> Result<(), Box<dyn std::error::Error>> { // Ожидание 500 мс sleep(Duration::from_millis(500)).await; // Выполнение операции с таймаутом 2 секунды let result = timeout(Duration::from_secs(2), async { // Длительная операция sleep(Duration::from_secs(1)).await; "результат операции" }).await?; println!("{}", result); Ok(()) } }