use std::time::Duration;
use tokio::{task, time::interval};
#[tokio::main]
async fn main() {
let mut interval = interval(Duration::from_secs(1));
let handle = task::spawn(async move {
loop {
interval.tick().await;
println!("tick");
}
});
handle.await.unwrap();
}
use tokio::time;
use chrono::{DateTime, Local};
async fn task_that_takes_a_second() {
let now: DateTime<Local> = Local::now();
println!("Current task time before is: {}", now.format("%Y-%m-%d %H:%M:%S"));
time::sleep(time::Duration::from_secs(2)).await;
let now: DateTime<Local> = Local::now();
println!("Current task time after is: {}", now.format("%Y-%m-%d %H:%M:%S"));
}
#[tokio::main]
async fn main() {
let mut interval = time::interval(time::Duration::from_secs(3));
for _i in 0..5 {
let now: DateTime<Local> = Local::now();
println!("Current main time before is: {}", now.format("%Y-%m-%d %H:%M:%S"));
interval.tick().await;
let now: DateTime<Local> = Local::now();
println!("Current main time mid is: {}", now.format("%Y-%m-%d %H:%M:%S"));
task_that_takes_a_second().await;
let now: DateTime<Local> = Local::now();
println!("Current main time after is: {}", now.format("%Y-%m-%d %H:%M:%S"));
}
}
Current main time before is: 2023-08-11 13:46:48
Current main time mid is: 2023-08-11 13:46:48 // 第一次,立即触发
Current task time before is: 2023-08-11 13:46:48
Current task time after is: 2023-08-11 13:46:50
Current main time after is: 2023-08-11 13:46:50
Current main time before is: 2023-08-11 13:46:50
Current main time mid is: 2023-08-11 13:46:51 // 距离上一次3秒
Current task time before is: 2023-08-11 13:46:51
Current task time after is: 2023-08-11 13:46:53
Current main time after is: 2023-08-11 13:46:53
Current main time before is: 2023-08-11 13:46:53
Current main time mid is: 2023-08-11 13:46:54 // 距离上一次3秒
Current task time before is: 2023-08-11 13:46:54
Current task time after is: 2023-08-11 13:46:56
Current main time after is: 2023-08-11 13:46:56
Current main time before is: 2023-08-11 13:46:56
Current main time mid is: 2023-08-11 13:46:57 // 距离上一次3秒
Current task time before is: 2023-08-11 13:46:57
Current task time after is: 2023-08-11 13:46:59
Current main time after is: 2023-08-11 13:46:59
Current main time before is: 2023-08-11 13:46:59
Current main time mid is: 2023-08-11 13:47:00 // 距离上一次3秒
Current task time before is: 2023-08-11 13:47:00
Current task time after is: 2023-08-11 13:47:02
Current main time after is: 2023-08-11 13:47:02
use tokio::time;
use chrono::{DateTime, Local};
async fn task_that_takes_a_second() {
let now: DateTime<Local> = Local::now();
println!("Current task time before is: {}", now.format("%Y-%m-%d %H:%M:%S"));
time::sleep(time::Duration::from_secs(5)).await;
let now: DateTime<Local> = Local::now();
println!("Current task time after is: {}", now.format("%Y-%m-%d %H:%M:%S"));
}
#[tokio::main]
async fn main() {
let mut interval = time::interval(time::Duration::from_secs(3));
for _i in 0..5 {
let now: DateTime<Local> = Local::now();
println!("Current main time before is: {}", now.format("%Y-%m-%d %H:%M:%S"));
interval.tick().await;
let now: DateTime<Local> = Local::now();
println!("Current main time mid is: {}", now.format("%Y-%m-%d %H:%M:%S"));
task_that_takes_a_second().await;
let now: DateTime<Local> = Local::now();
println!("Current main time after is: {}", now.format("%Y-%m-%d %H:%M:%S"));
}
}
Current main time before is: 2023-08-11 13:51:24
Current main time mid is: 2023-08-11 13:51:24
Current task time before is: 2023-08-11 13:51:24
Current task time after is: 2023-08-11 13:51:29
Current main time after is: 2023-08-11 13:51:29
Current main time before is: 2023-08-11 13:51:29
Current main time mid is: 2023-08-11 13:51:29 // 举例上一次超过3秒
Current task time before is: 2023-08-11 13:51:29
Current task time after is: 2023-08-11 13:51:34
Current main time after is: 2023-08-11 13:51:34
Current main time before is: 2023-08-11 13:51:34
Current main time mid is: 2023-08-11 13:51:34 // 举例上一次超过3秒
Current task time before is: 2023-08-11 13:51:34
Current task time after is: 2023-08-11 13:51:39
Current main time after is: 2023-08-11 13:51:39
Current main time before is: 2023-08-11 13:51:39
Current main time mid is: 2023-08-11 13:51:39 // 举例上一次超过3秒
Current task time before is: 2023-08-11 13:51:39
Current task time after is: 2023-08-11 13:51:44
Current main time after is: 2023-08-11 13:51:44
Current main time before is: 2023-08-11 13:51:44
Current main time mid is: 2023-08-11 13:51:44 // 举例上一次超过3秒
Current task time before is: 2023-08-11 13:51:44
Current task time after is: 2023-08-11 13:51:49
Current main time after is: 2023-08-11 13:51:49
use tokio::time::{timeout, Duration};
use tokio::time;
use chrono::{DateTime, Local};
async fn long_future() {
let now: DateTime<Local> = Local::now();
println!("Current task time before is: {}", now.format("%Y-%m-%d %H:%M:%S"));
time::sleep(time::Duration::from_secs(5)).await;
let now: DateTime<Local> = Local::now();
println!("Current task time after is: {}", now.format("%Y-%m-%d %H:%M:%S"));
}
#[tokio::main]
async fn main() {
for _i in 0..5 {
let now: DateTime<Local> = Local::now();
println!("Current main time before is: {}", now.format("%Y-%m-%d %H:%M:%S"));
let res = timeout(Duration::from_secs(1), long_future()).await;
let now: DateTime<Local> = Local::now();
println!("Current main time after is: {}", now.format("%Y-%m-%d %H:%M:%S"));
if res.is_err() {
println!("operation timed out");
}
}
}
pub fn interval_at(start: Instant, period: Duration) -> Interval
use tokio::time::{interval_at, Duration, Instant};
use chrono::{DateTime, Local};
#[tokio::main]
async fn main() {
let start = Instant::now() + Duration::from_secs(5);
let mut interval = interval_at(start, Duration::from_secs(3)); // 不会立即开始
let now: DateTime<Local> = Local::now();
println!("Current task time now is: {}", now.format("%Y-%m-%d %H:%M:%S"));
interval.tick().await; // ticks after 3s
let now: DateTime<Local> = Local::now();
println!("Current task time now is: {}", now.format("%Y-%m-%d %H:%M:%S"));
interval.tick().await; // ticks after 3s
let now: DateTime<Local> = Local::now();
println!("Current task time now is: {}", now.format("%Y-%m-%d %H:%M:%S"));
interval.tick().await; // ticks after 3s
let now: DateTime<Local> = Local::now();
println!("Current task time now is: {}", now.format("%Y-%m-%d %H:%M:%S"));
}
Current task time now is: 2023-08-11 19:34:30
Current task time now is: 2023-08-11 19:34:35
Current task time now is: 2023-08-11 19:34:38
Current task time now is: 2023-08-11 19:34:41
use tokio::time;
use chrono::{DateTime, Local};
use tokio::time::MissedTickBehavior;
async fn task_that_takes_a_second() {
let now: DateTime<Local> = Local::now();
println!("Current task time before is: {}", now.format("%Y-%m-%d %H:%M:%S"));
time::sleep(time::Duration::from_secs(5)).await;
let now: DateTime<Local> = Local::now();
println!("Current task time after is: {}", now.format("%Y-%m-%d %H:%M:%S"));
}
#[tokio::main]
async fn main() {
let mut interval = time::interval(time::Duration::from_secs(3));
interval.set_missed_tick_behavior(MissedTickBehavior::Delay);
for _i in 0..5 {
let now: DateTime<Local> = Local::now();
println!("Current main time before is: {}", now.format("%Y-%m-%d %H:%M:%S"));
interval.tick().await;
let now: DateTime<Local> = Local::now();
println!("Current main time mid is: {}", now.format("%Y-%m-%d %H:%M:%S"));
task_that_takes_a_second().await;
let now: DateTime<Local> = Local::now();
println!("Current main time after is: {}", now.format("%Y-%m-%d %H:%M:%S"));
}
}
在 Rust 的 tokio 库中,MissedTickBehavior 是一个枚举类型,表示当 Interval 频率计时器在某个周期中错过某个间隔时如何处理。具体来说,它有以下三个变体:
#[tokio::main]
async fn main() {
let mut interval_burst = time::interval(Duration::from_millis(5));
interval_burst.set_missed_tick_behavior(time::MissedTickBehavior::Burst);
let mut interval_delay = time::interval(Duration::from_millis(5));
interval_delay.set_missed_tick_behavior(time::MissedTickBehavior::Delay);
let mut count_burst = 0;
let mut count_delay = 0;
// 运行到20000次以上才会看出差异
loop {
select! {
_ = interval_burst.tick() => {
count_burst += 1;
println!("Burst: tick #{}", count_burst);
}
_ = interval_delay.tick() => {
count_delay += 1;
println!("Delay: tick #{}", count_delay);
}
}
}
}