这段代码:
use std::thread::sleep;
use std::time;
use std::sync::atomic::{AtomicU32, Ordering};
use tokio::time::Duration;
static REQUEST_RECV_V2: AtomicU32 = AtomicU32::new(0);
async fn no_msg_pro(s: String) {
println!("exectue no_msg_pro fun - str: {} begin!", s);
tokio::time::sleep(time::Duration::from_secs(5)).await;
//sleep(time::Duration::from_secs(5));
println!("exectue no_msg_pro fun - str: {} end!", s);
}
#[tokio::main]
async fn main() {
tokio::spawn(async {
loop {
sleep(time::Duration::from_secs(10));
REQUEST_RECV_V2.fetch_add(1, Ordering::Relaxed);
let s = format!("value--{:?}", REQUEST_RECV_V2);
println!("run process_msg fun - handle: {:?}", s);
tokio::spawn(async move {
no_msg_pro(s).await;
});
}
});
tokio::time::sleep(Duration::from_secs(100)).await;
}
运行代码时,第一次进入循环时不会触发
no_msg_pro
函数,只有第二次进入循环时no_msg_pro
函数才会运行。
得到这样的结果:
run process_msg fun - handle: "value--1"
run process_msg fun - handle: "value--2"
exectue no_msg_pro fun - str: value--1 begin!
exectue no_msg_pro fun - str: value--1 end!
我不知道为什么,你能告诉我原因吗!
不要使用 tokio 中阻塞的 anything 或一般的异步。异步任务是非抢占式,也称为协作多任务。它们不能被抢占(未安排),除非它们在
.await
点空闲。
std::thread::sleep
不提供.await
点,因此等待它会阻塞整个运行时(或多线程情况下的部分运行时)。
精髓:永远不要在
std::thread::sleep
函数中调用 async
。
tokio::time::sleep
代替;它确实提供了一个.await
点,允许运行时在睡眠时切换到另一个任务。
事实上,您的整个
use std::time;
和 use std::thread::sleep;
都是危险信号。将它们全部删除。
这是您的固定代码:
use std::sync::atomic::{AtomicU32, Ordering};
use tokio::time::{sleep, Duration};
static REQUEST_RECV_V2: AtomicU32 = AtomicU32::new(0);
async fn no_msg_pro(s: String) {
println!("execute no_msg_pro fun - str: {} begin!", s);
sleep(Duration::from_millis(500)).await;
println!("execute no_msg_pro fun - str: {} end!", s);
}
#[tokio::main]
async fn main() {
tokio::spawn(async {
loop {
sleep(Duration::from_secs(1)).await;
REQUEST_RECV_V2.fetch_add(1, Ordering::Relaxed);
let s = format!("value--{:?}", REQUEST_RECV_V2);
println!("run process_msg fun - handle: {:?}", s);
tokio::spawn(async move {
no_msg_pro(s).await;
});
}
});
sleep(Duration::from_secs(10)).await;
}
run process_msg fun - handle: "value--1"
execute no_msg_pro fun - str: value--1 begin!
execute no_msg_pro fun - str: value--1 end!
run process_msg fun - handle: "value--2"
execute no_msg_pro fun - str: value--2 begin!
execute no_msg_pro fun - str: value--2 end!
run process_msg fun - handle: "value--3"
execute no_msg_pro fun - str: value--3 begin!
execute no_msg_pro fun - str: value--3 end!
run process_msg fun - handle: "value--4"
execute no_msg_pro fun - str: value--4 begin!
execute no_msg_pro fun - str: value--4 end!
run process_msg fun - handle: "value--5"
execute no_msg_pro fun - str: value--5 begin!
execute no_msg_pro fun - str: value--5 end!
run process_msg fun - handle: "value--6"
execute no_msg_pro fun - str: value--6 begin!
execute no_msg_pro fun - str: value--6 end!
run process_msg fun - handle: "value--7"
execute no_msg_pro fun - str: value--7 begin!
execute no_msg_pro fun - str: value--7 end!
run process_msg fun - handle: "value--8"
execute no_msg_pro fun - str: value--8 begin!
execute no_msg_pro fun - str: value--8 end!
run process_msg fun - handle: "value--9"
execute no_msg_pro fun - str: value--9 begin!
execute no_msg_pro fun - str: value--9 end!