Здравствуйте, vdimas, Вы писали:
V>>>Э, нет. Эта корутина, по-сути, наследник shared_state у целевого future, представляющего собой состояние корутины. Т.е. этот shared_state заведомо необходимо делить м/у потоками.
EP>>Нет, корутины ортогональны future — их можно использовать вместе, но совсем необязательно. В коде Boost.Coroutine "future" вообще нигде нет.
V>Я имел ввиду stateless корутины из proposal для С++17.
Stackless корутины могут быть не такими.
EP>>Конечно, и даже готов показать как это именно возможно на примере stackless coroutine из Boost.Asio.
V>Еще раз, ты скопируешь состояние корутины/лямбды, но она пришла в это состояние по событиям из внешнего мира. Как ты скопируешь внешний мир?
А зачем копировать внешний мир?
V>Т.е. какова семантика происходящего при этом
Копируются/перемещаются все созданные поля плюс индекс текущего состояния этого конечного автомата.
V>и для чего это всё?
Например для того чтобы использовать обычные правила автоматических/stack объектов C++, а не аллоцировать кадр под корутину.
Для того чтобы можно было легко передавать её из одного места в другое.
Для того чтобы генераторы (т.е. yield value) — были ForwardIterator а не single pass InputIterator.
Для того чтобы можно было такую корутину сериализовать по сети.
EP>>future тут вообще не причём, stackless coroutine как фича языка должна брать код/функцию обычного вида и трансформировать её в класс-автомат, где поля это переменные из тела функции, а состояния — точки останова yield. В C# yield именно таким образом и реализован.
V>Если брать C#, то там для аналогичного служит async/await, где async является аналогом resumable из proposal для C++17. В обоих случаях сигнатуры async/resumable возвращают идентичный по назначению объект — Task/future.
Сигнатура тут тоже не причём.
EP>>future и подобное появляются только в частных случаях корутин применения типа await.
V>Дык, именно для await это всё, для этой самой точки автоматической передачи управления следующей задаче из очереди задач текущего потока.
Для этого в том числе. НО, это также достигается другими, лучшими методами.
V>Даже в примерах к stackless корутинам из Boost.Asio показано, что управление передаётся ручками через yield, где аргументом yield обычно служит некая блокирующая операция (т.е. операция, которая выполняется "где-то еще", но текущий поток должен быть блокирован на Task/future Wait/wait для ожидания окончания этой операции).
Вот как раз в stackless корутинах из Boost.Asio и показано как это может быть реализовано по другому — там не нужно вызывать аллокатор для корутины, это просто класс, объект которого можно создать любым из возможных способов, его можно скопировать, перемещать, сериализовать и т.п.
V>>>Сейчас proposal оперирует универсальной парадигмой resumable, где resumable ф-ии могут состоять из других resumable ф-ий.
EP>>Насколько я помню, там был далеко не единственный proposal (причём от разных авторов). В каком оно сейчас состоянии — не знаю, надо будет проверить.
V>Насчет resumable — один, уже довольно-таки устаканенный. Не удивлюсь, если GCC и MSVC реализуют его ДО 17-го года (как было с future, thread и т.д., когда GCC и MSVC выкатили свои реализации более чем за год до принятия С++11).
Мне тут скинули ссылки, оказывается автор Boost.Asio сделал другой proposal
N4244 — он как раз основан на дизайне stackless coroutine из Boost.Asio.
Также скинули
ссылку на дискуссию из std-proposals. Там как раз обсуждают различия этих предложений, и поднимают все аспекты упомянутые мной — аллокация корутин, копирование/перемещение, сериализация, multi-pass generators. Т.е. это не выдуманные мной проблемы, они реально есть, и они заботят не только меня.
Я надеюсь что proposal от Microsoft не пройдёт, а пройдёт от автора Boost.Asio (хотя там тоже есть некоторые моменты, и над ними тоже нужно работать, но они менее значительные).