Re[7]: Асинхронщина
От: B0FEE664  
Дата: 19.12.25 19:33
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Твой WaitingBlock сейчас везде называется Promise. Это не проблема и есть уже давно. Смотри пара std::promise/std::future. Проблема же не в отложенном ожидании как таковом, а в восстановлении всего контекста ожидания, что бы продолжить бизнес логику дальше, с того же места, где она прервалась на ожидание.


Не-а. promise/future — это примитивы. Если их прямо использовать, то понять что-либо будет несколько затруднительно. Поэтому я и предлагаю сделать обвязку в виде функциональных объектов. Комбинация таких объектов позволит организовывать код в простую и понятную последовательность.

  Скрытый текст
V>Вот пример:
V>result class::some_method1(params1_t... params)
V>{
V>    Что создаем на стеке (1)
V>    Что создаем на стеке (2)
V>    Что создаем на стеке (3)

V>    wair_for_io_operation (1) 
V>    wair_for_io_operation (2) 

V>    Что создаем на стеке (4)
V>    Что создаем на стеке (5)
V>    Что создаем на стеке (6)

V>    wair_for_io_operation (3) 
V>    wair_for_io_operation (4)

V>    Очищаем созданное на стеке (1)
V>    Очищаем созданное на стеке (2)
V>    Очищаем созданное на стеке (3)
V>    Очищаем созданное на стеке (4)
V>    Очищаем созданное на стеке (5)
V>    Очищаем созданное на стеке (6)
V>}

V>result class::some_method2(params2_t... params)
V>{
V>    Что создаем на стеке (1)
V>    Что создаем на стеке (2)
V>    Что создаем на стеке (3)

V>    wair_for_io_operation (1) 
V>    wair_for_io_operation (2) 

V>    Что создаем на стеке (4)
V>    Что создаем на стеке (5)
V>    Что создаем на стеке (6)

V>    wair_for_io_operation (3) 
V>    wair_for_io_operation (4)

V>    Очищаем созданное на стеке (1)
V>    Очищаем созданное на стеке (2)
V>    Очищаем созданное на стеке (3)
V>    Очищаем созданное на стеке (4)
V>    Очищаем созданное на стеке (5)
V>    Очищаем созданное на стеке (6)
V>}
V>
Нужно иметь возможность выполнять эти два метода параллельно, в зависимости от того, как завершаются операции ввода-вывода. В С++20 корутины между вызовами сохраняют объекты выделенные на стеке в куче и после ожидания заново копируют на стек в том же состоянии, для продолжения выполнения с прерванной точки. Как такое можно сделать на С++17 по твоему?

Насколько я понимаю, корутины в С++20 достаточно бесполезны. Нужно сразу С++23, в котором являются объекты, позволяющие нормально организовать код. Честно говоря, я не понимаю зачем понадобилось вводить ключевые слова, вроде co_yield. Для совмещения параллельности выполнения с ленивыми вычислениями мне это кажется излишним.

Вот если мы создали какой-то ленивый объект. Он хранит одно состояние и умеет переходить в следующее при выдаче результата. Хорошо. Очевидно, что если внутри этого объекта реализовать некое вычисление следующего состояния параллельно к работе основного потока, то мы получим сопрограмму. Чем это принципиально отличается от корутин — Зачем нужны co_await с co_return'ами —

Вот если посмотреть на тот псевдокод, что вы написали, то можно заметить, что он написан исключительно в процедурном стиле, здесь создаём, тут ждем, там запускаем. А где место объекту? Если же начать думать в парадигме объектов, то всё станет намного проще. Собственно, не спроста в C++23 пришли std::generator. Это закономерный и, к моему сожалению, эволюционный путь развития.
И каждый день — без права на ошибку...
Re[8]: Асинхронщина
От: Videoman Россия https://hts.tv/
Дата: 21.12.25 19:26
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Насколько я понимаю, корутины в С++20 достаточно бесполезны. Нужно сразу С++23, в котором являются объекты, позволяющие нормально организовать код. Честно говоря, я не понимаю зачем понадобилось вводить ключевые слова, вроде co_yield. Для совмещения параллельности выполнения с ленивыми вычислениями мне это кажется излишним.


Чем мне поможет С++23 в задачами с вводом вывода? Стандартизация самого механизма уже есть в С++20, а поддержки I/O не предвидится даже в С++29, насколько я понял. Всё равно всё придется делать самомому.


BFE>Вот если мы создали какой-то ленивый объект. Он хранит одно состояние и умеет переходить в следующее при выдаче результата. Хорошо. Очевидно, что если внутри этого объекта реализовать некое вычисление следующего состояния параллельно к работе основного потока, то мы получим сопрограмму. Чем это принципиально отличается от корутин — Зачем нужны co_await с co_return'ами —


Вычисление можно организовать параллельно. А как ожидать такие waiter'ы одновременно? Допустим у тебя 10 таких операций выполняется параллельно, все сильно разные по времени. Если ты раньше времени зависнешь на ожидании долгого события, то более быстрые останутся заблокированными. Как ты предлагаешь решить эту проблему?
Корутины сами решают какую из сопрограмм возобновить и в какой момент восстановить стек и продолжить.


BFE>Вот если посмотреть на тот псевдокод, что вы написали, то можно заметить, что он написан исключительно в процедурном стиле, здесь создаём, тут ждем, там запускаем. А где место объекту? Если же начать думать в парадигме объектов, то всё станет намного проще. Собственно, не спроста в C++23 пришли std::generator. Это закономерный и, к моему сожалению, эволюционный путь развития.


Генераторы не обязаны работать параллельно, там немного другая задача — передать управление и возобновить опять с прерванного места, при этом нет никаких ожиданий, поток CPU используется на все 100%. Такое я ещё могу представить как можно сделать без поддержки корутин.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.