Этот вопрос может в некоторой степени относиться к асинхронному c -программированию, чем к Rust. Но после того, как много гуглить, я думаю, что некоторые моменты отсутствуют. И так как я изучаю Rust, я бы сказал об этом на Rust.
Позвольте мне сначала дать понимание асин c -программирования --- В конце концов, это основа, может быть, я ошибаюсь или нет:
Для эффективной работы программы необходимо одновременное выполнение задач. Затем используется поток, и этот поток можно объединять всякий раз, когда нужны данные из потока. Но поток не достаточно для решения многих задач, как сервер. Затем используется пул потоков, но как извлечь данные, когда они необходимы, без информации о том, какой поток должен ожидать? Затем появляется функция обратного вызова (сокращенно cb). С cb следует учитывать только то, что нужно сделать в cb. Кроме того, чтобы процессор немного нагружался, появляется зеленая нить.
Но что, если асин-ожидающие вещи нужно делать один за другим, что приводит к "адскому обратному вызову"? Хорошо, появляется стиль «будущее / обещание», который позволяет коду выглядеть как syn c -код или, может быть, как цепочка (как в javascript). Но все же код выглядит не совсем красиво. Наконец, появляется стиль "async / await", который является еще одним синтактическим знаком c для стиля "будущее / обещание" И обычно «async / await» со стилем зеленых потоков называется «сопрограммой», будь то использование только одного собственного потока или нескольких собственных потоков над задачами asyn c.
====== =============================================
Насколько я знаю на этом этапе в качестве ключевого слова «await» может использоваться только в области действия «asyn c», и только «asyn c» функция может быть «ожидаемой». Но почему? И к чему он привык, так как уже есть «asyn c»? В любом случае, я тестировал приведенный ниже код:
use async_std::{task};
// async fn easy_task() {
// for i in 0..100 {
// dbg!(i);
// }
// println!("finished easy task");
// }
async fn heavy_task(cnt1: i32, cnt2: i32) {
for i in 0..cnt1 {
println!("heavy_task1 cnt:{}", i);
}
println!("heavy task: waiting sub task");
// normal_sub_task(cnt2);
sub_task(cnt2).await;
println!("heavy task: sub task finished");
for i in 0..cnt1 {
println!("heavy_task2 cnt:{}", i);
}
println!("finished heavy task");
}
fn normal_sub_task(cnt: i32) {
println!("normal sub_task: start sub task");
for i in 0..cnt {
println!("normal sub task cnt:{}", i);
}
println!("normal sub_task: finished sub task");
}
async fn sub_task(cnt: i32) {
println!("sub_task: start sub task");
for i in 0..cnt {
println!("sub task cnt:{}", i);
}
println!("sub_task: finished sub task");
}
fn outer_task(cnt: i32) {
for i in 0..cnt {
println!("outer task cnt:{}", i);
}
println!("finished outer task");
}
fn main() {
// let _easy_f = easy_task();
let heavy_f = heavy_task(3000, 500);
let handle = task::spawn(heavy_f);
print!("=================after spawn==============");
outer_task(5000);
// task::join_handle(handle);
task::block_on(handle);
}
Вывод, который я получил из теста:
1.Не важно ожидать asyn c sub_task или просто делать normal_sub_task (syn c version) в середине asyn c heavy_task (), код ниже (тяжелый l oop task2 ) не будет вырезать строку.
2. Не имеет значения, ожидая asyn c sub_task или просто выполняйте normal_sub_task (syn c version) в середине asyn c heavy_task ( ), external_task иногда обрезается в строке, ломая heavy_task1 или async_sub_task / normal_sub_task.
Поэтому, каково значение слова «await», кажется, что только ключевое слово «asy c» является используется здесь.
ссылка:
asyc_std
sing_dance_example из ржавчины asyncbook
модуль Задача в официальном модуле ржавчины
рекомендуемая статья ржавчины на этой неделе об asyn c -pro грамматика
еще одна статья о ржавчине и асинхронности c -программирование с использованием будущих ящиков
stackoverflow вопрос: Какова цель асинхронизации / ждите в Rust? вывод 2, который я получил, кажется, нарушается против того, что сказал Шепмастер: «... мы чувствовали, что асин c функции должны выполняться синхронно с первым ожиданием».