007 Rust 非同步程式設計,通過 join 執行 Future

linghuyichong發表於2020-07-01

在之前我們主要介紹了通過await和block_on執行Future,但是這兩種方式實際上都是順序執行的方式。

.await是在程式碼塊中按順序執行,會阻塞後面的程式碼,但是此時會讓出執行緒;block_on會阻塞直到Future執行完成。

本節我們介紹join巨集,可以同時執行多個Future。

join巨集允許在同時執行多個不同的Future並等待它們完成。

示例

  • 原始碼
//src/main.rs
use futures;
use tokio::runtime::Runtime;

async fn function1() {
    tokio::time::delay_for(tokio::time::Duration::from_secs(1)).await; //等待一秒鐘
    println!("function1 ++++ ");
}

async fn function2() {
    println!("function2 ++++ ");
}

async fn async_main() {
    let f1 = function1();
    let f2 = function2();

    // 使用await則會順序執行,使用join則會併發執行f1和f2
    // f1.await;
    // f2.await;
    futures::join!(f1, f2);
}

fn main() {
    let mut runtime = Runtime::new().unwrap();
    runtime.block_on(async_main());
    println!("Hello, world!");
}
  • Cargo.toml配置
[dependencies]
futures = "0.3.5"
tokio = { version = "0.2", features = ["full"] }

結果分析

如果在async_main中使用的await執行,則執行結果如下:

function1 ++++ 
function2 ++++ 
Hello, world!

如果在async_main中使用join執行,則執行結果如下:

function2 ++++ 
function1 ++++ 
Hello, world!

try_join和join巨集類似,唯一的區別就是,當執行傳送錯誤時就馬上返回。

示例

  • 原始碼
//src/main.rs
use futures::try_join;
use tokio::runtime::Runtime;
use std::io::Result;

async fn function1() -> Result<()> {
    tokio::time::delay_for(tokio::time::Duration::from_secs(10)).await;
    println!("function1 ++++ ");
    Ok(())
}

async fn function2() -> Result<()> {
    println!("function2 ++++ ");
    Ok(())
}

async fn async_main() {
    let f1 = function1();
    let f2 = function2();

    // f1.await;
    // f2.await;
    if let Err(_) = try_join!(f1, f2) {
        println!("Err!")
    }
}

fn main() {
    let mut runtime = Runtime::new().unwrap();
    runtime.block_on(async_main());
    println!("Hello, world!");
}
  • Cargo.toml配置檔案
[dependencies]
futures = "0.3.5"
tokio = { version = "0.2", features = ["full"] }
  • 執行結果
function2 ++++ 
function1 ++++ 
Hello, world!
本作品採用《CC 協議》,轉載必須註明作者和本文連結

令狐一衝

相關文章