nor*_*bjd 7 asynchronous rust async-await
我有以下async功能(实现并不重要):
async fn long_task(task_number: i32) {
// do some long work
println!("Task {} executed", task_number);
}
Run Code Online (Sandbox Code Playgroud)
我想同时运行n次这个函数,所以我定义了这个函数:
async fn execute_long_tasks_async(n: i32) {
let mut futures = Vec::new();
for i in 1..=n {
futures.push(long_task(i));
}
futures::future::join_all(futures).await;
}
Run Code Online (Sandbox Code Playgroud)
我正在使用该join_all函数来等待所有任务都执行完毕。然后我在我的中调用这个函数main:
fn main() {
futures::executor::block_on(execute_long_tasks_async(3));
}
Run Code Online (Sandbox Code Playgroud)
我的问题是任务是按顺序运行的:
Executing task 1
Task 1 executed
Executing task 2
Task 2 executed
Executing task 3
Task 3 executed
Run Code Online (Sandbox Code Playgroud)
但我希望它同时运行,我会得到类似的结果:
Executing task 1
Executing task 3
Executing task 2
Task 1 executed
Task 3 executed
Task 2 executed
Run Code Online (Sandbox Code Playgroud)
是否有替代方法可以futures::future::join_all并行运行所有任务?
我想用来await创建一个简单的示例来演示async和await。
Mat*_*247 14
join_all同时运行任务(不是并行)。它有一个限制,即只能在任务让步时才能在任务之间切换。此外,如果第一个任务还没有准备好,它总是更愿意执行第一个任务。
如果你的函数例如定义为
async fn long_task(task_number: i32) {
println!("Executing Task {}", task_number);
tokio::time::delay_for(Duration::from_secs(1)).await;
println!("Task {} executed", task_number);
}
Run Code Online (Sandbox Code Playgroud)
那么await函数中间的 / 挂起点将提供join_all运行其他函数的机会Future- 并且您将观察到预期的输出。
但是,如果long_task不产生(例如,因为它将是线程阻塞),则该函数将在其他任务开始之前运行完成:
async fn long_task(task_number: i32) {
println!("Executing Task {}", task_number);
std::thread::sleep(Duration::from_secs(1));
println!("Task {} executed", task_number);
}
Run Code Online (Sandbox Code Playgroud)
如果你有这样的功能,那么它们通常不太适合这个async世界。async函数的目的不是占用 CPU 资源,也不应该阻塞线程 - 以便同一执行器上调度的其他函数仍然可以运行。
一种可能为您提供更多并行性的替代方案是使用多线程异步运行时(例如 tokio)并将spawn每个异步函数作为单独的任务。在这种情况下,任务可以在单独的 CPU 核心和线程上运行,并且不会相互阻塞太多。然后,您可以使用join_all返回的集合JoinHandle来等待所有任务完成。
| 归档时间: |
|
| 查看次数: |
5194 次 |
| 最近记录: |