advance/async/getting-started #1077
Replies: 25 comments 25 replies
-
CPU 密集的任务很可能会一直霸着着【修改为:霸占着】 CPU。 |
Beta Was this translation helpful? Give feedback.
-
感觉同时载歌载舞这个例子并没用很好的体现出异步来。 |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
曲婉婷的例子可以改一改,毕竟有争议(滑稽 |
Beta Was this translation helpful? Give feedback.
-
第一部分的
和
建议统一一下,用同一个术语来指代 |
Beta Was this translation helpful? Give feedback.
-
菜鸟提问:block_on( ) 阻塞当前线程的意思是 会创建一个新的线程来运行future吗? |
Beta Was this translation helpful? Give feedback.
-
我就是回来提醒你们 rust 即将支持 |
Beta Was this translation helpful? Give feedback.
-
个人理解如下: 首先,future并不是多线程。 Rust多线程编程的情况如下: 线程 (通过 thread::spawn 创建的) CUP 备注:一旦语言线程通过 thread::sleep 方法被阻塞,说明 OS 线程被阻塞。 anync await 编程 future_A -------> 语言线程A -------> OS线程1 备注:调用 future_A 的 await 方法并不会阻塞语言线程A,此时的语言线程A还可以继续执行 future_B,C,D.。 猜测:如果,语言线程A里面的 所有 futrue 都处于 await 状态,语言线程A应该是处于了阻塞状态,也是会产生线程的上下文切换的。关于这个问题,还在研究中。 |
Beta Was this translation helpful? Give feedback.
-
我有一个例子,可能可以更简单的说明一个线程中运行多个future(task)的case:(交替打印结果,await阻塞当前task但不阻塞线程;) [dependencies]
futures = "0.3"
[dependencies.async-std]
version = "1.7.0"
features = ["attributes"] use core::time;
use std::time::Duration;
use async_std::task;
use futures::{executor::block_on, join};
async fn hello_world() {
for j in 0..10 {
task::sleep(time::Duration::from_secs(3)).await;
println!("hello, world!: {:?}", j);
}
}
async fn hello_cat() {
for i in 0..10 {
task::sleep(Duration::new(1, 0)).await;
println!("hello, kitty! : {:?}", i);
}
}
async fn async_main() {
let future1 = hello_world();
let future2 = hello_cat();
join!(future1, future2);
}
fn main() {
let f = async_main();
block_on(f);
} |
Beta Was this translation helpful? Give feedback.
-
[package]
name = "async_exp"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
async-std = "1.12.0"
futures = "0.3"
use std::time;
use futures::executor::block_on;
fn main() {
block_on(test())
}
async fn sing() {
async_std::task::sleep(time::Duration::from_secs(1)).await;
println!("sing! {:?}", std::thread::current().id());
}
async fn dance() {
println!("dance! {:?}", std::thread::current().id())
}
async fn test() {
let sing = sing();
let dance = dance();
futures::join!(sing, dance);
} 可以打印一下线程id |
Beta Was this translation helpful? Give feedback.
-
这一章翻来覆去看了三遍,我怎么感觉最后真正实现并发的,是join啊!其他的什么async await其实就起到一个标记作用,更多的可能是给编译器看的,表示这部分代码 可以 被并发的执行;但是真正去实现并发的还是join!,因为他可以同时等待多个异步任务。其他那些等待单个异步任务完成的选手,那执行起来就还是有点像同步。。。 |
Beta Was this translation helpful? Give feedback.
-
很像go里面的goroutine协程实现,底层跟线程也是M:N对应。并且在新版本对调度进行优化,不会产生让协程饿死的情况 |
Beta Was this translation helpful? Give feedback.
-
因此.await对于实现异步编程至关重要,它允许我们在同一个线程内并发的运行多个任务。 |
Beta Was this translation helpful? Give feedback.
-
https://blog.csdn.net/vince1998/article/details/138422536?spm=1001.2014.3001.5501 大家可以看看我写的博客,对作者代码进行了进一步的详细解释 |
Beta Was this translation helpful? Give feedback.
-
这么读下来,感觉 async 标记的代码块就是协程啊,多对一映射到一个 Rust 线程,Rust 线程和 OS 线程又是 1:1。同时因为 async 标记的语法块会被转换成实现了Future特征的状态机,async 代码块切换感觉就是协程切换而不是线程上下文切换,所以性能高点。 |
Beta Was this translation helpful? Give feedback.
-
async为什么不会引起线程上下文切换?我理解的是,如果线程A的cpu时间片用完了,线程B开始执行就会导致线程切换。 |
Beta Was this translation helpful? Give feedback.
-
async, await, future 都是用来注册任务的, 只有join!(A, B, C,,,)标记过的任务间可以互相切换, 任务如何安排到线程由rust完成, 线程如何调度由OS完成 |
Beta Was this translation helpful? Give feedback.
-
在learn_and_song这个任务因learn_song(虽然例子里的await其实跟没有差不多,因为只是learn_song只是返回一个对象,会立刻完成。但假设学歌是一个需要很长时间的异步操作)被await而挂起后,线程不会阻塞,而是去执行另一个异步任务dance,等到learn_song在后台完成了,才会继续进行learn_and_song。 |
Beta Was this translation helpful? Give feedback.
-
我看很多地方,都在拿rust和go做比较,这是不是说明,go其实也可以 |
Beta Was this translation helpful? Give feedback.
-
使用.await 章节,futures = "0.3.31" ,并不会提示warning. |
Beta Was this translation helpful? Give feedback.
-
这一段还是没看懂什么意思,在申明了async fn的函数内异步等待使用了.await的函数,我的理解是await相当于往调度器注册了这个函数并交给调度器做调度,那一个async fn内多个await函数是怎么保证顺序执行的呢?换句话说,我的疑问在于,既然是异步等待,怎么保证例子中是先learn_song再sing_song的呢? |
Beta Was this translation helpful? Give feedback.
-
文中提到async 代码的执行由社区的 async 运行时提供,例如 tokio 和 async-std,但是例子中并没有看到引用 tokio 或 async-std,实际上 block_on 就是一个最小化的运行时,看 block_on 的注释可以看到它是在当前线程运行,如果用 tokio,可以配置单线程或多线程。 |
Beta Was this translation helpful? Give feedback.
-
忽然有点疑惑,如果一个线程里只剩了一个future,那这个future被await挂起了,线程又找不到其他的future,是不是只能空转?这样的话会不会比线程阻塞还糟糕啊? |
Beta Was this translation helpful? Give feedback.
-
这一段咋没看懂呢,spawn_blocking 不就是tokio创建的吗,到底是要用tokio创建线程还是不要? |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
advance/async/getting-started
https://course.rs/advance/async/getting-started.html
Beta Was this translation helpful? Give feedback.
All reactions