Re[17]: Mногопоточность: C++ vs Erlang vs другие
От: Evgeny.Panasyuk Россия  
Дата: 08.06.15 20:43
Оценка:
Здравствуйте, 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 — и в обоих случаях это является мотивирующими примерами
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.