Я пытался изучить async / await и придумал простой код ниже:
const N: usize = 100000;
fn main() {
println!("Hello, world!");
let mut my_array = [0u32; N];
let mut my_vector = Vec::new();
for i in 0..my_array.len() {
my_array[i] = i as u32;
}
for i in 0..N {
my_vector.push((i * i) as u32);
}
let mut array_sum = 0;
let mut vector_sum = 0;
async_std::task::block_on(
async {
array_sum = sum_slice(&my_array).await;
vector_sum = sum_slice(&my_vector).await;
println!("Sum of array = {}", array_sum);
println!("Sum of vector = {}", vector_sum);
}
);
println!("Total sum = {}", array_sum + vector_sum);
}
async fn sum_slice(slice: &[u32]) -> u64 {
println!("Summing...{} to {}", slice.first().unwrap(), slice.last().unwrap());
slice.iter().fold(0, |a, &b| a + b as u64)
}
В этом коде два вызова функции sum_slice()
действительно выполняются асинхронно в двух разных потоках и параллельно?
Я спрашиваю это, потому что строка:
println!("Summing...{} to {}", slice.first().unwrap(), slice.last().unwrap());
всегда сначала печатает массив, например:
Summing...0 to 99999
Summing...0 to 1409865409
РЕДАКТИРОВАТЬ: изменил код таким образом ... какой из путей между (1) и (2) предпочтительнее?
use futures::join;
const N: usize = 10000;
#[async_std::main]
async fn main() {
let mut my_array = [0u32; N];
let mut my_vector = Vec::new();
for i in 0..my_array.len() {
my_array[i] = i as u32;
}
for i in 0..N {
my_vector.push((i * i) as u32);
}
//(1) st way
let array_sum = sum_slice(&my_array).await;
let vector_sum = sum_slice(&my_vector).await;
println!("Sum of array = {}", array_sum);
println!("Sum of vector = {}", vector_sum);
println!("Total sum = {}", array_sum + vector_sum);
//(2) nd way
async_std::task::block_on(
async {
let (array_sum, vector_sum) = join!(sum_slice(&my_array), sum_slice(&my_vector));
println!("Sum of array = {}", array_sum);
println!("Sum of vector = {}", vector_sum);
println!("Total sum = {}", array_sum + vector_sum);
});
}
async fn sum_slice(slice: &[u32]) -> u64 {
println!("Summing...{} to {}", slice.first().unwrap(), slice.last().unwrap());
slice.iter().fold(0, |a, &b| a + b as u64)
}
Спасибо за любую помощь.
РЕДАКТИРОВАТЬ 2:
Если Я пытаюсь запустить этот код в контексте выше, я получаю pani c:
use futures::join;
use std::sync::Arc;
const N: usize = 10000;
#[async_std::main]
async fn main() {
let mut my_array = [0u32; N];
let mut my_vector = Vec::new();
for i in 0..my_array.len() {
my_array[i] = i as u32;
}
for i in 0..N {
my_vector.push((i * i) as u32);
}
let a_arc = Arc::new(my_array);
let v_arc = Arc::new(my_vector);
let arr = a_arc.clone();
let vec = v_arc.clone();
println!("Try 0:");
async_std::task::spawn(
async move {
let future1 = sum_slice(&*arr);
let future2 = sum_slice(&*vec);
let (array_sum, vector_sum) = join!(future1, future2);
println!("Sum of array = {}", array_sum);
println!("Sum of vector = {}", vector_sum);
println!("Total sum = {}", array_sum + vector_sum);
});
}
async fn sum_slice(slice: &[u32]) -> u64 {
println!("Summing...{} to {}", slice.first().unwrap(), slice.last().unwrap());
slice.iter().fold(0, |a, &b| a + b as u64)
}
Я получаю следующую ошибку:
Try 0:
thread 'async-std/executor' panicked at 'cannot access stdout during shutdown', src\libstd\io\stdio.rs:487:25
stack backtrace:
Может кто-то указать ошибку я делаю, пожалуйста? Моя цель - запустить две задачи sum_slices () как asyn c друг друга и главного.
Спасибо.
ОБНОВЛЕНИЕ:
Думаю, я наконец-то понял это out.
const N: usize = 10000;
fn main() {
let mut my_array = [0u32; N];
let mut my_vector = Vec::new();
for i in 0..my_array.len() {
my_array[i] = i as u32;
}
for i in 0..N {
my_vector.push((i * i) as u32);
}
let task2 = task::spawn(async move {
let res = sum_slice(&my_array).await;
println!("done....task 2");
res
});
let task3 = task::spawn(async move {
let res = sum_slice(&my_vector).await;
println!("done....task 3");
res
});
task::block_on(async {
println!("waiting for the tasks...");
let res2 = task2.await;
let res3 = task3.await;
println!("task2 and task3 ended with result {}", res2+res3);
}
}
Теперь все вычисляется асин c друг с другом:
waiting for the tasks...
Summing...0 to 9999
Summing...0 to 99980001
done....task 2
done....task 3
task2 and task3 ended with result 333333330000