使用 tokio::spawn 函数未执行

问题描述 投票:0回答:1

这段代码:

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!

我不知道为什么,你能告诉我原因吗!

rust rust-tokio
1个回答
1
投票

不要使用 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!
© www.soinside.com 2019 - 2024. All rights reserved.