Эмуляция оператора await из языка C# 5. Данный proof-of-concept показывает, что идентичный синтаксис оператора await может быть достигнут с помощью Stackful Coroutines, демонстрируя что они предоставляют превосходящие возможности.
Цель данного proof-of-concept — привлечь внимание к Stackful Coroutines, а не эмуляция await'а сама по себе — так как с помощью сопроцедур можно достичь более высоких уровней инкапсуляции
int bar(int i)
{
// await is not limited by "one level" as in C#auto result = await async([i]{ return reschedule(), i*100; });
return result + i*10;
}
int foo(int i)
{
cout << i << ":\tbegin" << endl;
cout << await async([i]{ return reschedule(), i*10; }) << ":\tbody" << endl;
cout << bar(i) << ":\tend" << endl;
return i*1000;
}
void async_user_handler()
{
vector<future<int>> fs;
// instead of `async` at function signature, `asynchronous` should be
// used at the call place:for(auto i=0; i!=5; ++i)
fs.push_back( asynchronous([i]{ return foo(i+1); }) );
for(auto &&f : fs)
cout << await f << ":\tafter end" << endl;
}
"Оператор" await принимает std::future-like объект с поддержкой продолжений (например .then) и возвращает результат future (await future<int>(...), вернёт int).
В данном примере используется boost::async. Но такой подход может использоваться и с другими видами future, например PPL task::then и т.д.
Вывод:
1: begin
2: begin
3: begin
4: begin
5: begin
20: body
10: body
30: body
110: end
1000: after end
50: body
220: end
2000: after end
550: end
40: body
330: end
3000: after end
440: end
4000: after end
5000: after end
Re: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Я вот лет 10 назад экспериментировал с корутинами. Сделал реализацию под студию. Насколько я понимаю, аналогичная реализация сейчас добавлена в boost.
И так с тех пор она мне не пригодилась. Мне всё-таки кажется, что это всё мертворождённо. На современных многоядерных процессорах можно не изобретать псевдо-потоки,
а проще и выгодней пользоваться настоящей многопоточностью с настоящим параллелизмом.
Здравствуйте, Шахтер, Вы писали:
Ш>Мне всё-таки кажется, что это всё мертворождённо. На современных многоядерных процессорах можно не изобретать псевдо-потоки, Ш>а проще и выгодней пользоваться настоящей многопоточностью с настоящим параллелизмом.
А тут дело не только в псевдо/green-потоках.
Весь шум из-за того, что await это один из способов распрямить код использующий результаты "асинхронных" вызовов без блокирования вызывающего потока, сделать implicit continuations. Сами вызовы необязательно выполняются в одном потоке — в примере выше по async может использоваться пул реальных потоков.
Саттер, в последнем выступлении на C9, показывал примеры асинхронного кода WinRT и сказал что возможно в C++ добавят await.
Я не то чтобы совсем против await'а, но я в первую очередь предпочту сначала нормальные stackful coroutines — они намного мощнее await'а и как показывает пример выше на них можно легко реализовать как await-like код (для чего собственно я и сделал proof-of-concept), так и много чего другого.
Во-вторых, имхо, добавить stackful coroutines в ISO будет легче, чем await. В Boost.Coroutine сейчас довольно лаконичный интерфейс. А функции с await наверняка будут иметь много ограничений, либо спецификация будет громоздкой (C++ это всё-таки не C#).
Re[2]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Шахтер, Вы писали:
Ш>Здравствуйте, Evgeny.Panasyuk, Вы писали:
Ш>Я вот лет 10 назад экспериментировал с корутинами. Сделал реализацию под студию. Насколько я понимаю, аналогичная реализация сейчас добавлена в boost. Ш>И так с тех пор она мне не пригодилась. Мне всё-таки кажется, что это всё мертворождённо. На современных многоядерных процессорах можно не изобретать псевдо-потоки, Ш>а проще и выгодней пользоваться настоящей многопоточностью с настоящим параллелизмом.
В настоящей многопоточности нужна синхронизация, а в корутинах с этим все проще.
Так что если задача позволяет — часто корутины удобнее...
Re: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Эмуляция оператора await из языка C# 5. EP>Данный proof-of-concept показывает, что идентичный синтаксис оператора await может быть достигнут с помощью Stackful Coroutines, демонстрируя что они предоставляют превосходящие возможности. EP>Цель данного proof-of-concept — привлечь внимание к Stackful Coroutines, а не эмуляция await'а сама по себе — так как с помощью сопроцедур можно достичь более высоких уровней инкапсуляции
у Stackful Coroutines есть фатальный недостаток — они Stackful, и это значит нельзя сделать 10К сoroutines.
т.е. если ты пишешь сетевой сервер, ты не можешь использовать архитектуру "сопрограмма на клиент".
In Zen We Trust
Re[2]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Abyx, Вы писали:
A>у Stackful Coroutines есть фатальный недостаток — они Stackful, и это значит нельзя сделать 10К сoroutines. A>т.е. если ты пишешь сетевой сервер, ты не можешь использовать архитектуру "сопрограмма на клиент".
Я делал тест 200k корутин (Boost.Coroutine) — полёт нормальный. Из дополнительных настроек уменьшил default размер стэка (задаётся в конструкторе).
Re[3]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Добавить в стандарт можно, но не корутины сами по себе, а определённый набор функций для управления контекстом. Остальное можно построить на их основе разными способами.
Здравствуйте, enji, Вы писали:
E>Здравствуйте, Шахтер, Вы писали:
Ш>>Здравствуйте, Evgeny.Panasyuk, Вы писали:
Ш>>Я вот лет 10 назад экспериментировал с корутинами. Сделал реализацию под студию. Насколько я понимаю, аналогичная реализация сейчас добавлена в boost. Ш>>И так с тех пор она мне не пригодилась. Мне всё-таки кажется, что это всё мертворождённо. На современных многоядерных процессорах можно не изобретать псевдо-потоки, Ш>>а проще и выгодней пользоваться настоящей многопоточностью с настоящим параллелизмом.
E>В настоящей многопоточности нужна синхронизация, а в корутинах с этим все проще.
Есть такое. Просто корутины передают управление в фиксированных точках, что упрощает многие вещи.
E>Так что если задача позволяет — часто корутины удобнее...
Зато потоки обеспечат выигрыш в производительности.
Здравствуйте, Шахтер, Вы писали:
E>>Так что если задача позволяет — часто корутины удобнее...
Ш>Зато потоки обеспечат выигрыш в производительности.
С этим я не спорю
Лично у меня специфика такова, что задачи зависят в основном от скорости обмена по сети или по последовательному порту. А для таких случаев удобно большую часть задач крутить в одном потоке, а чтобы писать нормальный код в таком стиле и используются корутины.
Re: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Эмуляция оператора await из языка C# 5. EP>Данный proof-of-concept показывает, что идентичный синтаксис оператора await может быть достигнут с помощью Stackful Coroutines, демонстрируя что они предоставляют превосходящие возможности. EP>Цель данного proof-of-concept — привлечь внимание к Stackful Coroutines, а не эмуляция await'а сама по себе — так как с помощью сопроцедур можно достичь более высоких уровней инкапсуляции
Здравствуйте, night beast, Вы писали:
NB>честно говоря, поражаюсь вашему терпению. NB>сам бы уже несколько раз бросил что-либо доказывать упертым шарперам NB>
Не, это совсем не из-за "упёртых шарперов" — я в той теме даже не показывал
Я сделал этот прототип, сразу после того как посмотрел презентацию Саттера. Он рассказал, о том, что возможно в C++ добавят await. Я же предпочту сначала увидеть Stackful Coroutines в ISO, так как они более мощные, поэтому и сделал пример.
Re[3]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
EP>Я сделал этот прототип, сразу после того как посмотрел презентацию Саттера. Он рассказал, о том, что возможно в C++ добавят await. Я же предпочту сначала увидеть Stackful Coroutines в ISO, так как они более мощные, поэтому и сделал пример.
Здравствуйте, Шахтер, Вы писали:
Ш>Добавить в стандарт можно, но не корутины сами по себе, а определённый набор функций для управления контекстом. Остальное можно построить на их основе разными способами.
Это является и достоинством, и недостатком одновременно. Тем и плох C++, что почти всё можно сделать слишком большим количество разных способов. Это усложняет поддержку проектов, усложняет вхождение в проект новых людей.
Вон в C# способов раз-два и обчёлся. Зато даже джуниоры знают (ну или считают, что знают) async/await.
Re[5]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, koodeer, Вы писали:
K>Здравствуйте, Шахтер, Вы писали:
Ш>>Добавить в стандарт можно, но не корутины сами по себе, а определённый набор функций для управления контекстом. Остальное можно построить на их основе разными способами.
K>Это является и достоинством, и недостатком одновременно. Тем и плох C++, что почти всё можно сделать слишком большим количество разных способов. Это усложняет поддержку проектов, усложняет вхождение в проект новых людей. K>Вон в C# способов раз-два и обчёлся. Зато даже джуниоры знают (ну или считают, что знают) async/await.
Ну так С++ и не позиционировался никогда как дружественный к новичкам. У него несколько другие приоритеты
Здравствуйте, koodeer, Вы писали:
K>Здравствуйте, Шахтер, Вы писали:
Ш>>Добавить в стандарт можно, но не корутины сами по себе, а определённый набор функций для управления контекстом. Остальное можно построить на их основе разными способами.
K>Это является и достоинством, и недостатком одновременно. Тем и плох C++, что почти всё можно сделать слишком большим количество разных способов. Это усложняет поддержку проектов, усложняет вхождение в проект новых людей.
что-то на вхождение в Perl или там Python это не особо влияет я смотрю %) да и жалоб со от разработчиков что-то не слышно (в основном "нытье" от тех кто изучает).
Perl я могу читать только простой код, а вот на Python доводилось кодить разного... по количеству способов сделать одно и тоже С++ до него как ... ну вы поняли...
K>Вон в C# способов раз-два и обчёлся. Зато даже джуниоры знают (ну или считают, что знают) async/await.
Re[3]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Evgeny.Panasyuk, Вы писали:
A>>у Stackful Coroutines есть фатальный недостаток — они Stackful, и это значит нельзя сделать 10К сoroutines. A>>т.е. если ты пишешь сетевой сервер, ты не можешь использовать архитектуру "сопрограмма на клиент".
EP>Я делал тест 200k корутин (Boost.Coroutine) — полёт нормальный. Из дополнительных настроек уменьшил default размер стэка (задаётся в конструкторе).
200К которые счетчик инкрементили или это был сервер простецкий ?
Re[6]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, zaufi, Вы писали: Z>что-то на вхождение в Perl или там Python это не особо влияет я смотрю %) да и жалоб со от разработчиков что-то не слышно (в основном "нытье" от тех кто изучает). Z>Perl я могу читать только простой код, а вот на Python доводилось кодить разного... по количеству способов сделать одно и тоже С++ до него как ... ну вы поняли...
И это при том, что Питон именно в этом
There should be one — and preferably only one — obvious way to do it.
объявил священную войну Перлу,
который на самом деле проповедует вот что
Just because you CAN do something a particular way doesn't mean that you SHOULD do it that way. Perl is designed to give you several ways to do anything, so consider picking the most readable one.
но кого это волнует
ЗюЫю Кстати, я недавно натолкнулся на явную поддержку в Перле оптимизации хвостовой рекурсии — был приятно удивлен
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, night beast, Вы писали:
NB>>честно говоря, поражаюсь вашему терпению. NB>>сам бы уже несколько раз бросил что-либо доказывать упертым шарперам NB>>
EP>Не, это совсем не из-за "упёртых шарперов" — я в той теме даже не показывал EP>Я сделал этот прототип, сразу после того как посмотрел презентацию Саттера. Он рассказал, о том, что возможно в C++ добавят await. Я же предпочту сначала увидеть Stackful Coroutines в ISO, так как они более мощные, поэтому и сделал пример.
Stackfull точно не будет. Судя по голосовалке на этом сайте файберы использовало ажно 7% программистов и это при том, что голосовалка была создана ажно в 2005м, когда местные сиплюсники еще боялись признаться, что они уже дотнетчики
Re[4]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine
Здравствуйте, Ikemefula, Вы писали:
A>>>у Stackful Coroutines есть фатальный недостаток — они Stackful, и это значит нельзя сделать 10К сoroutines. A>>>т.е. если ты пишешь сетевой сервер, ты не можешь использовать архитектуру "сопрограмма на клиент". EP>>Я делал тест 200k корутин (Boost.Coroutine) — полёт нормальный. Из дополнительных настроек уменьшил default размер стэка (задаётся в конструкторе). I>200К которые счетчик инкрементили или это был сервер простецкий ?
while(true)
{
++counter;
yield();
}
Re[4]: [trick] await in C++ based on Stackful Coroutines from Boost.Coroutine