并发 async/await 与睡眠
Concurrent async/await with sleep
我想知道 关于 futures 的答案是否仍然适用于更新的语言结构 async/await
。似乎是这样,因为下面的代码打印:
hello
good bye
hello
虽然the guide说
The futures::join macro makes it possible to wait for multiple different futures to complete while executing them all concurrently.
显然,对于 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::thread::sleep
对异步一无所知,因此会使整个线程休眠。
Nodejs(通常 JavaScript)更多地围绕异步进行设计,因此语言原语和语言运行时更多 async-aware。
由于 standard/original thread::sleep
是阻塞的,结果是异步库提供了 async_std::task::sleep( ... )
,这是睡眠的非阻塞版本。它与 .await
(无括号)一起使用:
task::sleep::( Duration::from_millis( 1 ) ).await;
这个 sleep
与 unstable 版本具有相同的效果:yield_now 在某种意义上它
moves the currently executing future to the back of the execution queue, making room for other futures to execute. This is especially useful after running CPU-intensive operations inside a future.
所以我猜,预期用途是在任务计划执行长时间工作时“友善地”在未来之间共享线程的使用。
我想知道 async/await
。似乎是这样,因为下面的代码打印:
hello
good bye
hello
虽然the guide说
The futures::join macro makes it possible to wait for multiple different futures to complete while executing them all concurrently.
显然,对于 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::thread::sleep
对异步一无所知,因此会使整个线程休眠。
Nodejs(通常 JavaScript)更多地围绕异步进行设计,因此语言原语和语言运行时更多 async-aware。
由于 standard/original thread::sleep
是阻塞的,结果是异步库提供了 async_std::task::sleep( ... )
,这是睡眠的非阻塞版本。它与 .await
(无括号)一起使用:
task::sleep::( Duration::from_millis( 1 ) ).await;
这个 sleep
与 unstable 版本具有相同的效果:yield_now 在某种意义上它
moves the currently executing future to the back of the execution queue, making room for other futures to execute. This is especially useful after running CPU-intensive operations inside a future.
所以我猜,预期用途是在任务计划执行长时间工作时“友善地”在未来之间共享线程的使用。