代码之家  ›  专栏  ›  技术社区  ›  Saurabh Goyal

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

  •  0
  • Saurabh Goyal  · 技术社区  · 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();
    }
    
    

    ( Playground )

    输出

    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
    
    1 回复  |  直到 1 年前
        1
  •  2
  •   Aleksander Krauze    1 年前

    只有一项任务会运行,因为您 阻塞整个线程 使用 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 .那样会造成各种各样的死锁。如果你 需要 要在tokio中使用阻塞代码,请使用 tokio::task::spawn_blocking ,它将在另一个线程池上运行提供的闭包,专门用于阻塞任务。