1

Тема: Async - await

Поясніть, будь ласка, мастодонту, доки він на бронтозавра не перетворився: а в чому сенс цього синтаксичного цукру?
Просто в Rust оце додали, то я вже прочитав... а тепер не можу зрозуміти: нащо?
Якщо у нас є функція, і ми хочемо контролювати, коли її викликати, то її слід викликати саме в тому місці, де слід. Псевдокодом:

future = async f();
...
value = future.await();

Що заважає викликати f() в останньому рядку? Нащо там змінна future, яка не містить значення, але може бути перетворена на таке значення викликом wait?
Припустимо, ми маємо кілька можливих викликів, а хочемо скористатися лише одним:

if(...)future = async f():
else future = async g();
...
value = future.await();

Це - звичайний поліморфізм. Так, заради одного виклику кілька класів писати не дуже зручно. Але ж функції вже давно стали "громадянами першого класу", а посилання на них - і поготів:

if(...)f_to_call = f;
else f_to_call = g;
...
value = f_to_call();

Це, як на мене, значно зрозуміліше за всі ці future. Параметри? Загортаємо в лямбду:

if(...)f_to_call = lambda: f(x,y);
else f_to_call = lambda g(z);
...
value = f_to_call();

Чого саме я не розумію, чи розумію неправильно?

Подякували: leofun01, 221VOLT, sensei3

2

Re: Async - await

Мені схоже на "кооперативну багатозадачність" (типу Goroutine).
З https://rust-lang.github.io/async-book/ … uture.html:

Futures can be advanced by calling the poll function, which will drive the future as far towards completion as possible. If the future completes, it returns Poll::Ready(result). If the future is not able to complete yet, it returns Poll::Pending and arranges for the wake() function to be called when the Future is ready to make more progress. When wake() is called, the executor driving the Future will call poll again so that the Future can make more progress.

Типу можна зробити join!(future1, future2) і ці "фьючери" кооперативно в одном треді виконаються.
Підозрюю особливо зручно для IO, сокетів і тп, щоб не спаунити треди на ліво і на право.

Подякували: leofun01, koala2

3

Re: Async - await

Тобто ідея в тому, щоб "нарізати" виконання довгих завдань на маленькі poll-и, а потім зручно ними керувати?

4 Востаннє редагувалося 0x9111A (08.11.2019 12:28:40)

Re: Async - await

"Під каптуром" схоже на те. Проте, не думаю що під каптур треба буде лізти в 99% випадків.
Ідея швидше в моделі. Швика/ефективна робота з сучностями які можуть блокуватись а можуть і не блокуватись.

Подякували: 221VOLT1

5 Востаннє редагувалося 0x9111A (08.11.2019 12:33:22)

Re: Async - await

В с++ щось схоже є
https://lewissbaker.github.io/2017/11/1 … r-co-await
https://lewissbaker.github.io/2017/09/2 … ine-theory

6

Re: Async - await

Мені завжди здавалося, що це для зручної роботи з паралельними потоками. Щоб будь-який потік можна було запустити, призупинити, продовжити, зупинити. Типу такого: Coroutines (C++20).

Подякували: 221VOLT1

7 Востаннє редагувалося wander (08.11.2019 14:45:29)

Re: Async - await

leofun01 написав:

Мені завжди здавалося, що це для зручної роботи з паралельними потоками. Щоб будь-який потік можна було запустити, призупинити, продовжити, зупинити. Типу такого: Coroutines (C++20).

Корутини не дають ніякої змоги якось конфігурувати роботу з потоками, призупинити чи продовжити виконнання функції — так, а от щось робити з будь-яким (чи конкретно потрібним вам) потоком ні.

Подякували: leofun01, koala2

8 Востаннє редагувалося 221VOLT (08.11.2019 15:13:22)

Re: Async - await

мб оффтоп

Прихований текст

чесно кажучи, ніколи не розглядав Rust,
та на перший погляд здається,
що це щось, пов'язане з паралельною обробкою,
точніше, з отриманням результатів роботи паралельного процесу

перша асоціація -- receive з erlang
https://learnyousomeerlang.com/more-on- … your-state
https://learnyousomeerlang.com/more-on- … e-receives

9

Re: Async - await

Мені це нагадує std::task якби їх прийняли в стандарт

std::task<> usage_example() {
  // Calling function creates a new task but doesn't start
  // executing the coroutine yet.
  std::task<int> count_lines_task = count_lines("foo.txt");

  // ...

  // Coroutine is only started when we later co_await the task.
  int result = co_await count_lines_task;

  std::cout << "line count = " << result << std::endl;
}
Подякували: leofun01, 221VOLT2