Rust 標準庫中的 async/await (async-std)

vms_g發表於2019-12-06

簡介

現在的rust生態中,async/await在rust1.39中已經stable,其他庫還有futures 已經到0.3.x,還有就是本次說的這個async-std,async-std主要使用的就是標準庫中的Future,它也會依賴futures庫,包含futures庫中的一些特性,其實標準庫中的Future也是移植了futures庫中的Future.

async/await

async和await是可以分開的兩個術語,分開理解(針對Rust語言的,其他語言就很不一樣)

  1. async:產生一個Future物件,一個沒有任何作用的物件,必須由呼叫器呼叫才會有用
  2. await: 等待非同步操作完成(基於語義理解,其實很多情況只有呼叫future.await才是事實上去呼叫,具體是不是之前就開始執行,這個要看我們的呼叫器是什麼),這步是阻塞當前執行緒,這個語法屬於Future物件才能呼叫,而且必須要在async函式內

這列出三個非同步基礎作用

  1. 延遲計算:不需要立即得到結果
  2. 併發:多個操作併發執行,像多執行緒執行操作
  3. 獨立性:(暫時不理解)

async語法

1.在函式前新增async關鍵字

async fn async_test(){
​   println!("hello async");
}

2:async閉包

async || {
​   println!("hello async");
}

3: async move

fn async_test() -> impl Future<Output =Result<(),String>>{
    async move {
        println!("hello async");
        Ok(())
    }
}

再次提醒:帶有async關鍵字的函式直接呼叫是沒有任何作用的,比如下面的呼叫 async_test();不會列印任何東西

Future

上面說的三種,都會生成一個Future,看看Futrue定義

pub trait Future {
    type Output;
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}

執行器(task executor)

把task放到這來說,就把它理解為Future就是我們要做任務的一個細節描述,task呢就是這些根據這些細節描述去做,下面就是怎麼做的一些具體實現

block_on:阻塞呼叫,會阻塞當前執行緒直到有結果返回

spawn : 非同步併發呼叫,類似多執行緒同時呼叫,這個函式會返回 JoinHandle,

例子

待補充

檔案

use async_std::{
    fs::File, // 支援非同步操作的檔案結構體
    task, // 呼叫排程器
    prelude::* // Future或輸入輸出流
};

fn main() {
    // 阻塞執行Future
    task::block_on(file_test());
}

/// 讀取一個檔案中的64個位元組(十進位制表示)
async fn file_test() ->Result<(), std::io::Error>{
    let mut file = File::open("d:\\ABC.txt").await?;// ?號表示如果Err,會直接返回
    let mut buffer:[u8; 64] = [0; 64];// 建立一個64個長度的位元組陣列
    let n = file.read(&mut buffer).await?; // 每個await都是阻塞
    println!("The bytes: {:?}", &buffer[..n]);
    Ok(())
}

網路

待補充

結束語

從java轉過來的,有可能對async/await這個特性比較混亂,java中的Future非同步就是多執行緒呼叫,在rust中的Future又要複雜些

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章