Здравствуйте, vdimas, Вы писали:
EP>>А зачем копировать внешний мир?
V>Ну потому что корутина нужна не для галочки, а для обслуживания сигналов из внешнего мира.
Что ты понимаешь под копированием внешнего мира?
V>>>Т.е. какова семантика происходящего при этом
EP>>Копируются/перемещаются все созданные поля плюс индекс текущего состояния этого конечного автомата.
V>Т.е. хендл сокета тоже копируется? А дальше как?
Здесь хендл сокета это просто поле объекта. Если сокет не копируемый тип (как обычно и бывает), а только перемещаемый — то и корутина будет только перемещаемой — обычные правила C++.
V>Вот мы начали асинхронную операцию, после этого вошли в "ожидание", то бишь, сделали этой корутине yield, потом сделали копию корутины.
Если сокет не копируемый, то и корутина не скопируется.
V>>>и для чего это всё?
EP>>Например для того чтобы использовать обычные правила автоматических/stack объектов C++, а не аллоцировать кадр под корутину.
V>О каком "стеке" идет речь? После создания корутины надо выйти из текущего уровня стека, т.е. вернуть управление вызвавшему коду через future. А корутина путь живет себе и реагирует на события, продвигая как автомат своё тело.
Где она будет жить?
Например если это генератор вида (псевдокод):
generator<int> natural()
{
int i = 0;
while(true)
yield i++;
}
for(auto x : natural())
cout << x << endl;
То всё состояние генератора спокойно может жить как автоматический/временный объект. Если я захочу создать его в куче — то сделаю
new natural{}, и т.п. — это обычный тип.
Proposal же от microsoft подразумевает что будет некоторая явная аллокация, которую компилятор может оптимизировать, а может и нет.
V>Это про stackless. Фишка в том, что stackless корутина шагает по своим состояниям в общем случае в РАЗНЫХ потоках, из которых события приходят по push.
Даже stackful корутина из Boost.Coroutine может шагать по своим состояниям в разных потоках, я даже делал
пример на эту темуАвтор: Evgeny.Panasyuk
Дата: 25.09.14
.
V>Т.е., вот есть две асинхронные операции внутри такой корутины, оповещение по каждой из них продвигает корутину-автомат, но это оповещение приходит для каждой операции из другого потока. Поэтому, я не очень понимаю, что значит "правила автоматических объектов" для этого сценария.
Я про то что generator из примера выше это просто тип, объект которого можно создать разными способами:
generator a;
auto *b = new generator{}
new(buf) generator{};
auto c = make_unique<generator>();
auto d = make_shared<generator>();
EP>>Для того чтобы можно было легко передавать её из одного места в другое.
V>Как раз по указателю она передаётся легко.
Покажи как ты будешь легко передавать generator из примера выше по указателю, а конкретнее где под него будет выделятся память.
В моём варианте это просто небольшой объект размером в пару слов, который можно легко копировать.
V>То, что ты говоришь — оно интересно только для генераторов/трансформаторов и только для модели poll, типа как IEnumerable<>/yield в дотнете.
V>Поверь, даже в дотнете это наглухо совсем другое, чем async/await, хотя происходящее при этом как бы близкое. ))
Я не вижу смысла выбирать тяжёлую реализацию, которую трудно оптимизировать, с которой трудно работать, и которая предоставляет меньше возможностей.
EP>>Для того чтобы генераторы (т.е. yield value) — были ForwardIterator а не single pass InputIterator.
V>Это решается оберткой-итератором один раз и для всех таких корутин.
И как это решается? Сохранением всех пройденных значений? Вместо того чтобы иметь два объекта по два слова?
V>Спасибо за уточнение, я хоть понял, куда ты клонил.
V>Я думаю, что тут лучше не рассуждать о корутинах вообще, а применить этот подход прямо по назначению — развить концепцию итератора.
V>Потому что никакой универсальности, а отличие от resumable-ф-ий. Потому что только poll, и потому что только обязательный внешний шедуллинг, управляемый дынными, который уместен как раз в концепции итератора (оно же генератора/трансформатора) и нигде более.
На тех stackless корутинах о которых я говорю — реализуется и await и генераторы, и т.п. Они мощнее по возможностям.
EP>>Для того чтобы можно было такую корутину сериализовать по сети.
V>Ну это сфероконские мечты. Как ты будешь сериализовать корутину, которая обрабатывает сокет?
Ты говоришь про один из конкретных случаев. Я не говорю сериализация нужна во всех случаях, так же как и копирование.
Мьютекс нельзя сериализовать по сети — так что теперь откажемся от сериализации вообще?
V>Я же говорю, упомянутое тобой — совсем отдельный класс задач.
Который решается в рамках stackless корутин.
EP>>>>future и подобное появляются только в частных случаях корутин применения типа await.
V>>>Дык, именно для await это всё, для этой самой точки автоматической передачи управления следующей задаче из очереди задач текущего потока.
EP>>Для этого в том числе. НО, это также достигается другими, лучшими методами.
V>Пока никто не показал.
V>Не приводи как аргумент stackless корутины из буста, плиз )
Почему? Я же не говорю что их нужно повторять в точности до синтаксиса и всех неудобств.
V>Потому что это фигня в сравнении с await, если честно.
На них реализуется и await, и yield.
Да, есть синтаксические ограничения, неудобства и неоптимальности — но как раз для этого и нужно изменение языка.
V>Потому что никакого контроля со стороны компилятора. Потому что одним неверным чихом можно всё поломать.
Именно поэтому и нужна стандартная фича.
EP>>Вот как раз в stackless корутинах из Boost.Asio и показано как это может быть реализовано по другому — там не нужно вызывать аллокатор для корутины, это просто класс, объект которого можно создать любым из возможных способов, его можно скопировать, перемещать, сериализовать и т.п.
V>Одна тонкость — это всё не нужно, в тех сценариях, для которых, собсно, корутины разрабатываются.
Это нужно как минимум для генераторов, и мигрирующий лёгких процессов.
EP>>Мне тут скинули ссылки, оказывается автор Boost.Asio сделал другой proposal N4244 — он как раз основан на дизайне stackless coroutine из Boost.Asio.
V>Это стоит назвать чем-то вроде итератора, дабы не вводить людей в заблуждение.
Это именно stackless coroutine.
EP>>Я надеюсь что proposal от Microsoft не пройдёт, а пройдёт от автора Boost.Asio.
V>Чур тебя))
V>Это ортогональные техники для непересекающихся сценариев.
Да ладно? И там и там реализуется await/async, и там и там реализуется yield — и в обоих случаях это является мотивирующими примерами