【发布时间】:2022-02-04 05:19:52
【问题描述】:
我想知道this rather old question 关于期货的答案是否仍然适用于更新的语言结构async/await。似乎是这样,因为下面的代码打印:
hello
good bye
hello
虽然the guide 说
futures::join 宏可以等待多个不同的 futures 完成,同时同时执行它们。
很明显,对于sleep,这是许多其他异步系统(例如node.js)中预期行为的转移。
有什么根本原因会这样吗?
use std::time::Duration;
use std::thread;
async fn sayHiOne() {
println!( " hello " );
thread::sleep( Duration::from_millis( 3000 ) );
println!( " good bye " );
} // ()
async fn sayHiTwo() {
println!( " hello " );
} // ()
async fn mainAsync() {
let fut1 = sayHiOne();
let fut2 = sayHiTwo();
futures::join!( fut1, fut2 );
} // ()
fn main() {
block_on( mainAsync() );
} // ()
附加:实际线程预期的行为(I)
fn main() {
let fut1 = do_async( move || {
println!( "hello" );
thread::sleep( Duration::from_millis( 3000 ) );
println!( "good bye" );
});
let fut2 = do_async( move || {
println!( "hello" );
});
fut1();
fut2();
}
use std::thread;
use std::time::Duration;
use std::sync::mpsc::channel;
fn do_async<TOut, TFun>( foo: TFun ) -> (impl FnOnce()-> TOut)
where
TOut: Send + Sync + 'static,
TFun: FnOnce() -> TOut + Send + Sync + 'static
{
let (sender, receiver)
= channel::< TOut >();
let hand = thread::spawn(move || {
sender.send( foo() ).unwrap();
} );
let f = move || -> TOut {
let res = receiver.recv().unwrap();
hand.join().unwrap();
return res;
};
return f;
} // ()
【问题讨论】:
-
如果你使用 std 的睡眠,也就是阻塞睡眠,你显然不能期待好的结果。
-
顺便说一句,我完全不明白你在问什么
-
@Stargateur 并发函数可以由单个线程执行,并且看起来仍然是并行的。如果其中一个执行阻塞操作,则线程跳转到另一个。如果不是这样,并且在 rust 中我们必须默认使用实际线程,那么具有并发异步函数的意义何在?
-
“如果其中一个执行阻塞操作,线程跳转到另一个”线程怎么知道你调用了阻塞函数,即使是这种情况,它还能做什么它 ?!?如果你想要异步行为,请使用来自 tokio 的 sleep async,你不能混合阻塞和异步,并且神奇地期望它会解决。 Rust 与操作系统很接近。操作系统有阻塞 api 和异步 api。如果你使用阻塞 api,你的选择不要怪异步 Rust。再说一次,我不明白你问什么。顺便说一句,异步 rust 非常非常难以理解。
-
@Stargateur 很明显,“并发系统”应该 - 在引擎盖下 - 不惜一切代价实现它所宣传的目标。毕竟,那是样板代码。
标签: rust async-await thread-sleep