为什么 Tokio 单线程风格不提供任何并发性?

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

当我使用flavor =“current_thread”运行下面的代码时,我只看到第一个任务的输出,而不是另一个任务的输出。我的理解是,即使在单线程执行中,异步代码也可以并发运行。我错过了什么?

use std::{
    thread,
    time::{Duration, SystemTime},
};

#[tokio::main(flavor = "current_thread")]
async fn main() {
    let handle_1 = tokio::spawn(async move {
        loop {
            println!("{:?} Hello from 1", SystemTime::now());
            thread::sleep(Duration::from_millis(2000))
        }
    });
    let handle_2 = tokio::spawn(async move {
        loop {
            println!("{:?} Hello from 2", SystemTime::now());
            thread::sleep(Duration::from_millis(5000))
        }
    });
    handle_1.await.unwrap();
    handle_2.await.unwrap();
}

(游乐场)

输出

SystemTime { tv_sec: 1719896401, tv_nsec: 253252588 } Hello from 1
SystemTime { tv_sec: 1719896403, tv_nsec: 253411156 } Hello from 1
SystemTime { tv_sec: 1719896405, tv_nsec: 253504834 } Hello from 1
SystemTime { tv_sec: 1719896407, tv_nsec: 253627641 } Hello from 1
SystemTime { tv_sec: 1719896409, tv_nsec: 253785910 } Hello from 1
SystemTime { tv_sec: 1719896411, tv_nsec: 254074102 } Hello from 1
SystemTime { tv_sec: 1719896413, tv_nsec: 254410243 } Hello from 1
SystemTime { tv_sec: 1719896415, tv_nsec: 254574553 } Hello from 1
SystemTime { tv_sec: 1719896417, tv_nsec: 254955748 } Hello from 1
SystemTime { tv_sec: 1719896419, tv_nsec: 258449707 } Hello from 1
SystemTime { tv_sec: 1719896421, tv_nsec: 258703255 } Hello from 1
SystemTime { tv_sec: 1719896423, tv_nsec: 258839315 } Hello from 1
SystemTime { tv_sec: 1719896425, tv_nsec: 259088384 } Hello from 1
SystemTime { tv_sec: 1719896427, tv_nsec: 259232553 } Hello from 1
SystemTime { tv_sec: 1719896429, tv_nsec: 260017836 } Hello from 1
rust async-await concurrency rust-tokio
1个回答
0
投票

只有一个任务会运行,因为您“阻塞了整个线程”。使用 tokio::time::sleep 与运行时通信,任务应该在睡眠时产生。 use std::{ time::{Duration, SystemTime}, }; #[tokio::main(flavor = "current_thread")] async fn main() { let handle_1 = tokio::spawn(async move { loop { println!("{:?} Hello from 1", SystemTime::now()); tokio::time::sleep(Duration::from_millis(2000)).await; } }); let handle_2 = tokio::spawn(async move { loop { println!("{:?} Hello from 2", SystemTime::now()); tokio::time::sleep(Duration::from_millis(5000)).await; } }); handle_1.await.unwrap(); handle_2.await.unwrap(); }

一般来说,您不应该在 
async

中使用 blocking 代码。这样可能会导致各种死锁。如果您

需要
在tokio中使用阻塞代码,请使用tokio::task::spawn_blocking,它将在另一个线程池上运行提供的闭包,专门用于阻塞任务。

© www.soinside.com 2019 - 2024. All rights reserved.