【发布时间】:2020-02-15 13:24:43
【问题描述】:
这个问题可能比 Rust 更多地与异步编程有关。但是在谷歌上搜索了很多之后,我认为仍然缺少一些点。而且由于我正在学习 Rust,所以我会用 Rust 的方式来描述它。
先说说我对async-programming的理解---毕竟这是基础,也许我错了:
为了使程序高效运行,并发处理任务是必不可少的。然后使用线程,只要需要来自线程的数据,就可以加入线程。但是线程不足以处理许多任务,就像服务器一样。然后使用了线程池,但是在没有关于应该等待哪个线程的信息的情况下,如何在需要时获取数据?然后回调函数(简称cb)出现。有了cb,只需要考虑cb中需要做的事情。此外,为了减少 cpu 的开销,出现了绿色线程。
但是如果异步等待的事情需要一个接一个地做,导致“回调地狱”怎么办?好的,“future/promise”样式出现了,它让代码看起来像同步代码,或者可能像一个链(就像在 javascript 中一样)。但是代码仍然看起来不太好。最后,出现了“async/await”风格,作为“future/promise”风格的另一种语法糖。而且通常,带有绿色线程样式的“async/await”称为“协程”,无论是仅使用一个本地线程还是使用多个本地线程处理异步任务。
==============================================
据我所知,as关键字“await”只能在“async”函数的范围内使用,并且只有“async”函数才能被“awaited”。但为什么?以及它是用来做什么的,因为已经有“异步”了? 无论如何,我测试了下面的代码:
use async_std::{task};
// async fn easy_task() {
// for i in 0..100 {
// dbg!(i);
// }
// println!("finished easy task");
// }
async fn heavy_task(cnt1: i32, cnt2: i32) {
for i in 0..cnt1 {
println!("heavy_task1 cnt:{}", i);
}
println!("heavy task: waiting sub task");
// normal_sub_task(cnt2);
sub_task(cnt2).await;
println!("heavy task: sub task finished");
for i in 0..cnt1 {
println!("heavy_task2 cnt:{}", i);
}
println!("finished heavy task");
}
fn normal_sub_task(cnt: i32) {
println!("normal sub_task: start sub task");
for i in 0..cnt {
println!("normal sub task cnt:{}", i);
}
println!("normal sub_task: finished sub task");
}
async fn sub_task(cnt: i32) {
println!("sub_task: start sub task");
for i in 0..cnt {
println!("sub task cnt:{}", i);
}
println!("sub_task: finished sub task");
}
fn outer_task(cnt: i32) {
for i in 0..cnt {
println!("outer task cnt:{}", i);
}
println!("finished outer task");
}
fn main() {
// let _easy_f = easy_task();
let heavy_f = heavy_task(3000, 500);
let handle = task::spawn(heavy_f);
print!("=================after spawn==============");
outer_task(5000);
// task::join_handle(handle);
task::block_on(handle);
}
我从测试中得到的结论是:
1.无论是async Heavy_task()中间等待async sub_task还是做normal_sub_task(sync version),下面的代码(heavy loop task2)都不会插队。
2.无论是等待async sub_task还是只是在async heavy_task()中间做normal_sub_task(同步版本),outer_task有时会插队,破坏heavy_task1或async_sub_task/normal_sub_task。
所以“await”是什么意思,这里好像只用了关键字“asyc”。
参考:
sing_dance_example from rust asyncbook
module Task in official rust module
recommended article of rust this week about async-programming
another article about rust thread and async-programming using future crates
stackoverflow question:What is the purpose of async/await in Rust? 我得到的结论 2 似乎违反了 Shepmaster 所说的“......我们认为异步函数应该与第一个等待同步运行。”
【问题讨论】:
-
如果 async/await 的工作方式与 C# 中相同,那么它不是为了并行化,而是让当前线程在等待某个 IO 任务完成时可以做其他工作。而你没有任何
-
请注意,您的代码中没有任何内容实际上是异步的。你甚至有 blocking 调用 (
println!) 和计算。您不能只将async关键字添加到函数中以使其异步,这需要更多的工作(否则它可以完全自动化,并且我们不需要新的关键字)。 -
你需要复习并发的基础知识。您的基本理解有些不准确。
标签: multithreading asynchronous rust async-await