Rust async 理解和初步编写


Rust async 理解和初步编写

运行环境:Win10 x64, rustc 1.57.0, 作者:乌龙哈里,日期:2021-12-31


std::tread::spawn 这个函数。
首先我们要把 use std::thread::sleep; 改成 use std::thread::{sleep,spawn};,然后就能愉快地去改main() 主函数了。具体改造见如下:

use std::thread::{sleep,spawn};


fn main(){
    prepare();
    //spawn
    //英 [sp??n]
    //v.产卵;引发;引起;导致;造成
    //n.(鱼、蛙等的)卵
    let t1=spawn(cooking);
    let t2=spawn(wash_vegetable);
    t1.join().unwrap();
    t2.join().unwrap();
}
/*output:
prepare:1
prepare:2
prepare:3
prepare:4
prepare:5
rice cooking...
cooking...9
vegetable washing:101
vegetable washing:102
cooking...8
vegetable washing:103
cooking...7
vegetable washing:104
cooking...6
vegetable washing:105
cooking...5
cooking...4
cooking...3
cooking...2
cooking...1
cooking...0
rice cooked!!!
*/

看见输出了,果然在煮饭的过程中插入洗菜了。
引入线程按下面的套路写,就能跑起来了。

1、let 线程名 = spawn( 函数名 );
2、线程名.join();
其实 spawn() 返回值是 JoinHandle,先这么理解。

这里要吐槽一下,网上好多教程都是复杂得一塌糊涂,对于我这个非科班的业余人士来说和看天书差不多。还是自己使劲啃,自己动手写才能理解,不需要那么高大上的例子。

线程弄出来了,后面看了异步的种种,都在balabala...说线程很重等等,好吧,我们尝试来学习先进的技术吧。

Crate async_std 和 async-std。 我的基本理解是:async 和 await 其实是一种标记,需要在同步的函数前标记个 async,调用时末尾标记个.await。和 thread 的调用方式差不多。
首先得改写工程项目的 cargo.toml :

[dependencies]
async-std = { version = "1.2.0", features = ["attributes"] }

接着需要在程序头引用 use async_std::task::spawn;
所以下面 main() 主函数需要加入编译条件:#[async_std::main]。改造具体如下:

// ref:https://docs.rs/async-std/latest/async_std/index.html
// cargo.toml
// [dependencies]
// async-std = { version = "1.2.0", features = ["attributes"] }
use std::thread::sleep;
use async_std::task::spawn;
use std::time::Duration;

fn prepare(){
    //prepare before cooking rice
    for i in 1..6 {
        println!("prepare:{}",i);
        sleep(Duration::from_millis(500));
    }
}

async fn cooking(){
    println!("rice cooking...");
    for i in (0..10).rev(){
        println!("cooking...{}",i);
        sleep(Duration::from_millis(500));
    }
    println!("rice cooked!!!");
}

async fn wash_vegetable(){
    for i in 101..106{
        println!("vegetable washing:{}",i);
        sleep(Duration::from_millis(500));
    }
}

#[async_std::main]
async fn main(){
    prepare();
    let a1=spawn(cooking());
    let a2=spawn(wash_vegetable());
    a1.await;
    a2.await;
}

/*output:
prepare:1
prepare:2
prepare:3
prepare:4
prepare:5
rice cooking...
cooking...9
vegetable washing:101
cooking...8
vegetable washing:102
cooking...7
vegetable washing:103
cooking...6
vegetable washing:104
cooking...5
vegetable washing:105
cooking...4
cooking...3
cooking...2
cooking...1
cooking...0
rice cooked!!!
*/

大功告成。终于简单的会用 async 了。
总结一下用途就是,耗时过大的函数需要同步时,在其函数头前标记个 async。调用时在其调用者的 handle 后加个 .await。其他需要同时使用这段时间的函数同样处理。