Rust 并发与 join 和 tokio

Rust concurrency with join and tokio

我正在尝试 运行 两个与 join 并行的函数。

我的代码很简单:

tokio = { version = "1.14.0", features = ["full"] }
use tokio::join;
use std::thread::sleep;
use std::time::{Duration, Instant};

async fn fn_1() -> i8 {
  sleep(Duration::from_secs(2));

  2
}

async fn fn_2() -> i8 {
  sleep(Duration::from_secs(2));

  1
}

#[tokio::main]
async fn main() -> () {
  let now = Instant::now();

  println!("start: {:#?}", now.elapsed());

  let a = fn_1();
  let b = fn_2();

  join!(a, b);

  println!("end: {:#?}", now.elapsed());
}

但是无论我做什么,这都需要 4 秒 —2s + 2s—,如果我没记错的话应该需要 2 秒:

start: 37ns
end: 4.01036111s

有什么我遗漏的吗?

您正在调用 std 的睡眠函数,该函数使 OS 线程进入睡眠状态,而您的程序正在 运行 开启。如果您改为调用 tokio::time::sleep 函数,则应同时评估期货。

要在执行中启用实际并行性,您需要使用 tokio::task::spawn 让 运行 时间决定哪个线程 运行 产生的未来。

要进一步了解阻塞是什么,我推荐这个优秀的博客 post: https://ryhl.io/blog/async-what-is-blocking/