LINUX.ORG.RU

Как понять асинхонщину в Rust?

 , ,


0

5

В Rust какая-то очень «самобытная» асинхронщина, понять её сложно. Итак, необходимый минимум - реализовать трейт Future. Дольше веселее - есть несколько каких-то малопонятных сущностей, которые за что-то там отвечают, пока непонятно, за что.

Читал кучу мануалов, они из серии: https://sun1-16.userapi.com/impg/cTOihOqKWsJSPD6uBUB6KTQZY823V6f3TzS9Tw/5VAn_b_1JUI.jpg?size=1080x1080&quality=96&proxy=1&sign=3ec0c8687655c3ac555d4b06874cfc49&type=album

Как правильно достать значение из Future? 101 вопрос. Когда Future реализуется сам, а когда его необходимо реализовать самому? Я так понял, логика реализуется в poll(), нет?

Мне нужно, например, читать стдаут порождённого процесса или поток миди-данных в рандомное время на вводе.

Кто распишет вменяемый хеллоуворлд, скину на пиво;)

★★★★★

Как понять асинхонщину в Rust?

Шаг 1. Получить имя Carl Lerche при рождении.

Сейчас ещё куда ни шло. async/await и улучшения в борроу-чекере поуменьшили количество невменяемых сообщений об ошибках при робких попытках писать асинхронный код. Раньше было ещё хуже.

ilammy ★★★
()
Ответ на: комментарий от anonymous

Анониму идёт сразу по известному адресу.

WatchCat ★★★★★
()
Ответ на: комментарий от WatchCat

Асинхронщина на сях тот ещё оксюморон

О, ещё один растовик пробивает дно. Учи историю. В Windows 1.0-3.2 не было потоков, и был только один процесс на ВСЕ Windows программы, поэтому там всё писали на сях и на корутинах. Всё асинхронно. Умели же писать, когда я ещё не родился :)

А сейчас пошли дебилоиды, поэтому для них сделали раст, потому что для сей у них нет и не будет мозгов….

fsb4000 ★★★★★
()
Ответ на: комментарий от fsb4000

Лол. Ты попал пальцем в небо. Впрочем для ЛОРа это норма.

WatchCat ★★★★★
()
Ответ на: комментарий от fsb4000

А обычно ты более сдержан к брату Харконену. Что такое лапсик, юхевбэддей?

anonymous
()

зачем тебе вообще асинхронный код если в расте есть из коробки многопоточность, ты пытаешься перенести какой-то код с языков в которых ее нет, но есть асинхронность?

anonymous
()
Ответ на: комментарий от meliafaro

И что тебе мешает держать отдельный поток для всех этих «событий, случающихся в произвольное время»?

Я же надеюсь ты не один из тех ребят которые слепо внемлют любой ахинеи из букваря, подобной той что приводится в качестве оправдашек для использования асинхронного выполнения кода в букваре по расточку, которую ты цитируешь своими словами?

anonymous
()
Ответ на: комментарий от meliafaro

Ну давай расскажи нам что тебя натолкнуло на данные выводы.

anonymous
()
Ответ на: комментарий от hateyoufeel

Перечисли по пунктам отличительные свойства монад, удовлетворяя которым, что-то может быть монадой, и затем примени их к async.

anonymous
()

Для начинающих подключаешь async-std (или tokio) и фигачишь

#[async_std::main]
async fn main() {
  some_library.await?;
}

Если хочешь сам писать либы, то придется вкуривать видосы типа https://www.youtube.com/watch?v=9_3krAQtD2k Самая основная мысль в том, что в рантайме, который предоставляется либой лежат фьючи, которые либо спят либо работают. Есть реакторы, которые еполят сокеты и будят фьючи. Главное разобратся с устройством будильника.

q0tw4 ★★★★
()

логика реализуется в poll()

poll должен исполнятся быстро. Его задача поставить задачу для IO и настроить будильник или сообщить что всё готово. Байтики с сеточки читает отдельный поток, который спит если делать нечего

q0tw4 ★★★★
()
Последнее исправление: q0tw4 (всего исправлений: 1)
Ответ на: комментарий от q0tw4

придется вкуривать видосы типа

I was surprised to find the video is 4 hours long.

Great introduction of async programming in Rust. As the async/await got stabilized in recent rust releases, could you re-illustrate the concepts to us again?

вся суть раста :)

anonymous
()

Модель асинхронщины в расте самое примитивное дерьмо, но что-то тебе даже это сложно даётся. А в соседнем треде из себя эксперта строил, но ладно.

Есть некий примитив, пусть будет твоё Future. Это просто option, т.е. ты можешь для него вызвать «есть значение».

У тебя есть функция, предположим:

f() {
  return f().await;
}

Она преобразуется в, условно:

f() {
  Future x = f().await;
  // при втором запуске оно "прыгнет" сюда.
  if(!x.has()) return;
  return x.value();
}

Далее модель предполагает просто запуск милларда раз этой функции, пока значение не появится в Future.

Когда Future реализуется сам

Никогда.

Я так понял, логика реализуется в poll(), нет?

Нет, в poll ты реализуешь этот, условно, option, который потом будут долбить. Ты возвращаешь либо none, либо значение. Где ты будешь его брать - твои проблемы.

rafyibofye
()

Для начинающих — как в любом другом языке: при объявлении асинхронной функции пишешь async fn, при вызове асинхронной функции пишешь await.

Как правильно достать значение из Future?

Просто future.await.

Когда Future реализуется сам, а когда его необходимо реализовать самому?

Асинхронная функция типа async fn() -> X возвращает значение типа impl Furure<X>, самому реализовывать трейт Future не надо, пока сам этого не захочешь.

Мне нужно, например, читать стдаут порождённого процесса или поток миди-данных в рандомное время на вводе.

Просто юзай соответствующие функции из tokio или async-std.

anonymous
()
Ответ на: комментарий от rafyibofye

Никогда

Ну почему же. Можно в вебасме реализовывать свою фьючу. Ну или для работы с какимто железом, которое не через сокеты представлено (ну там драйвер например пишешь). А порой приходится когда узаешь стороннюю либу, которая не умеет в async_std и tokio сама, а весь твой код на async-await построен

q0tw4 ★★★★
()

Так, на всякий случай, дисклеймер: про Руст я начал читать 3 дня назад. Что б вам такие сценарии попадались на третий день самообучения Сишечке по K&R😏🤬

meliafaro ★★★★★
() автор топика
Ответ на: комментарий от q0tw4

Ну почему же. Можно в вебасме реализовывать свою фьючу.

Нельзя, боже. Почему вам так сложно разобраться даже в своей пропаганде? Реализация Future - это реализации функции, условно, get() => none|Some(T). Нельзя с ней ничего сделать, только вызов сверху.

Ты перепутал poll/push - изучи разницу.

rafyibofye
()
Ответ на: удаленный комментарий

А можно не на примере сокетов, а на примере, например, чтения из файла? Я тут не сервер разворачиваю.

meliafaro ★★★★★
() автор топика
Ответ на: удаленный комментарий

Ото ти впоротий. Будильник называется std::task::Waker, он передаётся в метод poll() через аргумент cx типа Context. дальше разбирать сей бред не имеет смысла.

anonymous
()
Ответ на: комментарий от meliafaro

Тут понимание у секты настолько никакущие, что и читать ничего ненужно. У тебя проблема не с этим, а в принципе с пониманием.

У тебя есть два варианта - нихрена не понимать и воспринимать всё как магию, как делает 99.(9)% раст-адептов. Именно потому они здесь.

Либо понимать, но тогда нахрена тебе раст? Раст нужен тем, кто не состоялся в рамках общей конкуренции. Это равносильно умеющему бегать сесть в инвалидную каляску. Но такие есть, но они так же состоялись, только на уровне понимания чуть выше рядового.

В результате мир просто не знает(практически) адептов раста, которые могут что-то понимать. Там их единицы на каждую фичу. Все остальные ретранслируют херню.

Далее просто идёшь и пытаешься написать async на сишке, разбираешься с тем, что такое push/poll. Хотя это должно быть очевидно. Далее ты понимаешь какие у этого есть проблемы и как они решаются.

rafyibofye
()
Ответ на: комментарий от meliafaro

Если у тебя 99% времени потоку нечем заняться, тебе вообще не нужна ни асинхронщина, ни потоки. Пиши синхронный код.

anonymous
()
Ответ на: комментарий от meliafaro

Сокет ничем не отличается от файла, да и для чтения файлов никакой async нахрен не упал. Тебе в принципе никакой async дерьма ненужен. Это всё херня.

Если ты хочешь какое-то асинхронное api, то ничего для сокетов/файлов не изменится. Ты точно так же берёшь fd и какой-то мультиплексор, который будет тебе выдавать евенты. В линуксе актуальный api - это урина, но я сомневаюсь, что где-то раст-дошколята что-то на ней реализовали. Там скорее всего фейчина псевдоасинхронная какая-то, либо на древнем aio.

rafyibofye
()
Ответ на: комментарий от anonymous

Реакция на появление новых данных должна быть в рил-тайм. Нет возможности проверять их в начале длинного цикла обработки ВСЕГО.

meliafaro ★★★★★
() автор топика
Ответ на: комментарий от meliafaro

Без кода или его описания, нельзя сказать есть возможность или нет.

В любом случае, пул потоков это распространенная практика. Ты для начала посмотри во что выливается overhead на thread и на async рутину. Не говоря уже о том что рутины будут заведомо хуже по скорости чем потоки. А потом посмотри как снизу реализованы эти рутины, станет понятно, что они в общем-то не нужны.

anonymous
()
Ответ на: комментарий от meliafaro

Самое удивительное то, что даже js-адепты больше о пулл-модели знают. У них там такая же херня в react, 1в1 модель. И вот представь в какую ты клоаку попал, если даже жс-адепты имеют понимание куда более глубокое, нежели здесь.

Но и возможно это тебе поможет. Иди почитай про react у жабаскрипта. Там ты поймёшь куда больше, нежели здесь.

Там тебе куда быстрее станет очевидно, что такое реакторы и для чего они нужны. И как из poll-дерьма делается push-пародия.

rafyibofye
()
Ответ на: комментарий от anonymous

Тут кто-то спрашивал, почему эти функции под капотом юзают обычные синхронные API в пуле потоков. Просто в линуксе до недавнего времени не было юзабильного асинхронного API для работы с файлами, т. к. было не нужно. Типичный жёсткий диск всё равно не поддерживает большое количество параллельных операций, достаточно десятка обычных тредов, чтобы его полностью насытить. В последнее время с развитием SSD становится актуально, поэтому пилят io_uring, но оно пока далеко от мейнстрима, поэтому в tokio и async-std пока не завезли, хотя есть отдельные крейты.

anonymous
()
Ответ на: удаленный комментарий

ты сишку не знаешь, судя по тому мусору

Блин, в той сишке я писал максимально показательный код для демонстрации. В реальности так никто не пишет, разумеется. Разошёлся тут.

Ну ладно, я уже понял, ты не фанат Ржавы. Мне бы вот только кто-нибудь накидал простенький хелло-ворлд на чистом языке без Токио и прочих фреймворков. Создатели целую книжку написали на тему, но вот толку-то.

meliafaro ★★★★★
() автор топика
Ответ на: комментарий от vertexua

Да, читал. Но это на будущее. Пока я основы на Раст с трудом понимаю, хотя вроде в теории понимаю асинхронщину.

meliafaro ★★★★★
() автор топика
Ответ на: комментарий от meliafaro

рилтайм и асинк - разные полюса. Рилтайм это когда быстрый пинг, асинк - это когда большой поток запросов. Смысл асинка - редко переключать контекст. Хотя цикл обработки всего не такой уж длинный, он спит на еполе и просыпается только когда ядро уже прочитало данные с какого-то сокета.

не на примере сокетов

Ну файловые дескрипторы можно мешать с сокетами в одном еполе. Правда насколько я смотрел, асинк это обычно про сокеты, а не файлы. Вряд ли ты станешь читать сразу тысячу файлов, а на несколько вполне можно выделить потоки.

q0tw4 ★★★★
()
Последнее исправление: q0tw4 (всего исправлений: 1)
Ответ на: комментарий от meliafaro

про Руст я начал читать 3 дня назад

Тогда забудь про асинк. Он для серверов и тех, кто знает что делает (тут вам не js, где промисы во все апи)

q0tw4 ★★★★
()
Последнее исправление: q0tw4 (всего исправлений: 1)
Ответ на: комментарий от meliafaro

В общем, все эти токио-хренокие это не про async, а просто костыли для poll-дерьма. Осознай это.

Повторю. Иди посмотри на жабаскрипт, и так же советую всем раст-адептам. Посмотрю на любую реактивную либу. Как там в рантайме строятся зависимости. Вот этим и занимается этот асинк-рантайм. А не тем, о чём ты думаешь.

В нормальном языке, в том же C++ async, используется push-модель. Да и по всей скриптухе так же push-модель. https://t.me/proriv_zaparti/57246 - можешь почитать тут. Там ниже было обсуждение.

rafyibofye
()
Ответ на: комментарий от meliafaro

Забавный ты. Читать про реализацию ты не хочешь, пытаешься наныть пример, но при этом говоришь что нет толку, так толку то нет от тебя, а не от мануала.

anonymous
()
Ответ на: комментарий от q0tw4

Он для серверов

На этом мусоре никто не пишет никакие серверы. Слишком мусор.

тут вам не js, где промисы во все апи

В жс push-модель и там ненужен никакой говнорантайм. Они там во все поля именно поэтому.

rafyibofye
()
Ответ на: комментарий от meliafaro

Главное не тратить время на лонгриды царя, он там просто собой любуется, технического содержания в тексте нету

vertexua ★★★★★
()
Последнее исправление: vertexua (всего исправлений: 1)
Ответ на: удаленный комментарий

Успокойся пудель. Никто ему не обязан рожать примеры так же как и тебе, чтобы развенчать твои заблуждения, хочешь что-то доказать иди и сам читай исходный текст расточка, тем более явно видно что он даже не старается понять что-то, просто пришел и ноет, как ты приблизительно, только в другой плоскости нытья.

Шансов у него понять столько же, сколько и у любого кто умеет читать. Но он - лентяй, до такой степени, что даже сам не смог найти букварь на официальном сайте, на этом в принципе можно было закрывать тред.

anonymous
()

Если интерес теоретический, то лучше написать свой (плохой) планировщик. Начать можно отсюда https://rust-lang.github.io/async-book/02_execution/04_executor.html

Простой пример https://github.com/spacejam/extreme

Еще простой пример https://cloudhead.io/popol/ но здесь нету async/await синтаксиса.

Future – это просто трейт, никакой магии, планировщик имеет очередь значений реализующих этот трейт и дергает их по одному. Сложности добавляет ввод-вывод и многопоточность. В токио уже есть планировщик и все необходимое, в 99% случаев на практике его хватает.

vlad9486
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.