返回介绍

12.2 任务

发布于 2024-10-13 11:25:32 字数 2597 浏览 0 评论 0 收藏 0

以同步相似的方式编写异步代码,编译器和运行时完成异步执行。

  • async fn 创建同名包装,返回实现 Future 特征的匿名类型对象。
  • Future 是惰性(延迟计算)的,须交由执行器作为任务(task)执行。
  • async move 转移所有权。
use futures::executor::block_on;

async fn add(x: i64, y: i64) -> i64 {   // fn add(..) -> impl Future {
  return x + y;             //  async_do ..
}                     // }

fn main() {
  let f = add(8, 9);         // Future
  let v: i64 = block_on(f);      // Executor & wait.return
  
  println!("{:?}", v);
}
(gdb) p f

$2 = core::future::from_generator::GenFuture<demo::add::{async_fn_env#0}> (
  demo::add::{async_fn_env#0}::Unresumed{x: 8, y: 9}
)

async 函数中,用 Future.await 执行并等待结果返回。

  • 等待期间,运行时调度线程执行其他任务。
  • 同一函数内的多个等待,按代码顺序串行。
  • 多线程执行器可能将任务切换到其他线程。

可以认为,以 await 为分割线将逻辑切成多个任务块。
两个任务块之间,执行器调度线程执行其他 Future ,稍后再断点恢复。

use futures::executor::block_on;

async fn a() -> i32 {
  println!("a");
  10
}

async fn b() -> i32 {
  println!("b");
  20
}

async fn test() {
  let x = a().await;     // 只能在 async 内使用。
  let y = b().await;     // 目标是 Future/async。
  println!("{}, {}", x, y);  // 函数内,a、b 串行。
}

fn main() {
  block_on(test());
}

// a
// b
// 10, 20

不同执行方式:

  • block_on :在当前线程执行,结束后返回结果。
  • join! :在异步块内轮询多个任务,待全部结束后,按顺序返回结果。
use futures::{join, executor::block_on};

async fn test() {
  
  // 可用于代码块。
  let a = async {
    println!("a");
    10
  };

  let b = async {
    println!("b");
    20
  };

  let v = join!(a, b);   // 如果是函数,须 join!(a(), b()) 。
  println!("{:?}", v);
}

fn main() {
  block_on(test());
}

// a
// b
// (10, 20)

实现

利用异步版标准库,验证 async/await 执行。

# Cargo.toml

[dependencies]
futures = "0.3"
async-std = "1.12.0"
chrono = "0.4"
use std::time::Duration;
use futures::join;
use async_std::task::{block_on, sleep};
use chrono::Local;

async fn a() {
  println!("a: {:?}", Local::now());
  sleep(Duration::from_secs(2)).await;
}

async fn b() {
  println!("b: {:?}", Local::now());
  sleep(Duration::from_secs(2)).await;
}

async fn c() {
  println!("c: {:?}", Local::now());
  sleep(Duration::from_secs(3)).await;
}

async fn test() {
  join!(async {
    a().await;
    b().await;
  }, c());
}

fn main() {
  block_on(test())
}

/*

a: 2022-07-18T14:11:04   其中,a、c 同时启动。
c: 2022-07-18T14:11:04   而 b 是在 a 结束后。
b: 2022-07-18T14:11:06

*/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文