advance/async/getting-started #1077
Replies: 29 comments 27 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.
-
use futures::join;
pub struct Song{
pub name: String,
pub author: String,
}
pub async fn learn_song() -> Song{
Song{
name: String::from("let it go"),
author: String::from("aliSha")
}
}
pub async fn sing_song(song:&Song) {
// thread::sleep(Duration::from_secs(1));
for i in 0..10{
println!("I will sing :{i}");
}
println!("Let me show song: song name:{},song author: {}",song.name,song.author)
}
pub async fn dance() {
for i in 20..30{
println!("i will dance{i}");
}
println!("too happy too dance!")
}
pub async fn sing_dance(){
let songs = learn_song().await;
let ss = sing_song(&songs);
let d = dance();
println!("i can sing and dance");
join!(ss,d);
}
### 结果真是印证了密集计算霸站CPU。 |
Beta Was this translation helpful? Give feedback.
-
.await语法。。。为啥不能对齐js await语法糖 |
Beta Was this translation helpful? Give feedback.
-
啊,日子似乎永无止境 |
Beta Was this translation helpful? Give feedback.
-
如果有JS基础,那这个设计还挺好理解的,异曲同工之妙 async function fetchUserInfo() {
// web请求
const fetchResponse = await fetch("https://api.github.com/users/octocat")
// 等待请求完成后将数据解析成JSON
const result = await fetchResponse.json()
// 写日志
await writeFetchLog(result.data)
return result.data
}
async function fetchDeviceInfo() {
// web请求
const fetchResponse = await fetch("https://xxx/device/info")
// 等待请求完成后将数据解析成JSON
const result = await fetchResponse.json()
// 写入本地
await writeLocalDeviceInfo(result.data)
return result.result
}
function main() {
// 请求用户信息
fetchUserInfo()
// 请求设备信息
fetchDeviceInfo()
} 对于主线程,会同时执行两个异步任务,每个异步任务内的执行顺序通过await语法糖保证是同步的 也就对应上文的 |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
advance/async/getting-started
https://course.rs/advance/async/getting-started.html
Beta Was this translation helpful? Give feedback.
All reactions