LINUX.ORG.RU

Корутины в C++17

 ,


0

5

Всем хорошего кода!

Прочитал на Хабрахабре статью о предстоящих корутинах в C++17. Ознакомьтесь с ней, кому интересно :

https://habrahabr.ru/post/278267/

Так вот, там такая неплохая критика proposal о корутинах.

Я не специалист в C++, но мне интересно, что думает каждый по поводу корутин : лучше С#-подобный вариант или всё же Boost. Coroutine?

Перемещено leave из talks

лучше С#-подобный вариант или всё же Boost. Coroutine?

Второе. Но каких-то оригинальных доводов не приведу.

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

если судить по доводам из статьи, то да, бустовая реализация лучше вроде как.

Но мне кажется, что в комитете сидит довольно много сторонников первого варианта.

zamazan4ik ★★
() автор топика

На мой взгляд async/await выглядит гораздо понятнее. Когда смотрел на реализацию корутин в Boost, сломал себе мозг.

Vovka-Korovka ★★★★★
()
Ответ на: комментарий от zamazan4ik

бустовые корутины разве не сохраняют состояния регистров? от этого и хотели уйти, судя по презентации.

ossa ★★
()
Ответ на: комментарий от ossa

я не использовал ни разу Boost.Coroutine и не имею представления, как оно работает. Постараюсь почитать про это и просветиться

zamazan4ik ★★
() автор топика
Последнее исправление: zamazan4ik (всего исправлений: 1)

вот нашёл 1 интересный коммент на хабре в защиту suspend-up варианта :

Как фанат асинхронного программирования в стиле C#, могу в качестве ответа привести возражения против бустовой реализации.

Boost.Coroutines использует модель "suspend-down", которая является тайной. Смотря на прототип функции, невозможно сказать, не начнет ли она переключать контексты. Пропущенное переключение контекста может плохо кончиться — ведь не все функции являются реентерабельными, и другая сопрограмма может вызвать такую функцию пока она выполняется в соседней сопрограмме.

Особенно остро эта проблема встанет в случае взаимодействия библиотек на разных языках — так, среда .NET CLR не является реентерабельной. Если вызвать через P/Invoke нативную библиотеку, которая переключит контекст и сделает обратный вызов — возникнет неустранимая ошибка.

Асинхронные обещания модели "suspend-up" куда легче пробрасываются сквозь код на другой платформе.

Кроме того, реализация Boost.Context платформозависима, ее надо переделывать под каждую новую платформу. Причем платформой тут является комбинация ОС и архитектуры процессора. Модель же async/await реализуется на высоком уровне одинаково для всех платформ.

Кроме того, модель "suspend-down" довольно активно пожирает пространство оперативной памяти под стек. Если для модели "suspend-up" требуется не такое большое число потоков, и для каждого из них можно выделить "обычный" стек, а основная требуемая задачам память будет выделяться из кучи кусками — то в модели "suspend-down" свой стек нужен под каждую задачу, и их придется делать маленькими. А отсюда — высокая вероятность переполнения стека при ошибке в угадывании требуемого размера.

zamazan4ik ★★
() автор топика
Ответ на: комментарий от zamazan4ik

Блин, не надо вставлять цитаты как код. Я задолбался уже крутить по горизонтали, чтобы это прочитать.

nexfwall ★★★★
()

Лично мне async/await нравиться больше. Весь вопрос в реализации этого, чую опять что-нибудь изговняют в угоду мифическим идеалам.

И не надо слушать всяких мудаков, которые предлагают отложить решение. Такими темпами это будет только в С++20, плюс пока ещё в компиляторах поддержат. Я к тому времени уже поседею.

dnf83
()
Ответ на: комментарий от zamazan4ik

Ну вот и ответ:

ведь не все функции являются реентерабельными, и другая сопрограмма может вызвать такую функцию пока она выполняется в соседней сопрограмме.

в С++ большинство функций являются реентерабельными (если не содержат статических данных)

в случае взаимодействия библиотек на разных языках — так, среда .NET CLR не является реентерабельной.

ну ой тогда: в С# у них не было выбора и теперь бомбит, что в С++ можно сделать по-нормальному, с потерей совместимости с их любименьким .NET

anonymous
()
Ответ на: комментарий от dnf83

И хорошо, что отложат. Обдумают получше, а не с костылями потом возиться. Их и так в плюсах достаточно.

Deleted
()
Ответ на: комментарий от zamazan4ik

Насколько я понял из просмотра какой-то презентации от MS, в которой они уже использовали ключевые слова с префиксом co_ (co_await...) корутина от MS - это обычный функтор, который с помощью компилятора и трех ключевых слов превращается конструкцию по синтаксису похожую на обычную функцию. В общем это нужно реализовывать в виде библиотеки, а не пропихивать в стандарт языка (правда на обычную функцию это не будет похоже, а все же останется функтором).

Кроме того, реализация Boost.Context платформозависима

Давайте сравним количество платформ, которые поддерживает Boost::Context и реализация от MS.

ее надо переделывать под каждую новую платформу. Причем платформой тут является комбинация ОС и архитектуры процессора.

Бустовые корутины используют Boost::Context, которому для работы нужно сишное ABI на вызов функции (которое жестко стандартизовано под все платформы и менять его - значит отказаться от обратной совместимости) и то, что сишная программа использует стек (не уверен, что другие платформы вообще существуют). Чтобы сломать работу Boost::Context, нужно сделать весьма странный способ обработки исключений (впрочем, МС вполне это по силам при большом желании). В результате, все что нужно Boost::Context для работы либо стандартизировано, либо почти невозможно сделать с ним несовместимым.

Модель же async/await реализуется на высоком уровне одинаково для всех платформ.

Ага, и ее можно и нужно реализовать в виде библиотеки.

Кроме того, модель «suspend-down» довольно активно пожирает пространство оперативной памяти под стек.

Пожирает, но виртуальную память. Физическая выделяется только при ее использовании. Т.е. делается mmap с резервированием любого количества памяти, в который страницы физической памяти добавляются при первом обращении к соответствующему адресу.

Смотря на прототип функции, невозможно сказать, не начнет ли она переключать контексты.

Вопрос: async_read() будет переключать контексты? А вообще, сначала хотели сделать, чтобы асинхронный код выглядел как синхронный, а теперь вот это... Вы уж определитесь.

По поводу того, что корутина может быть вызвана из одного потока, а продолжить выполнение после переключения на другом. Это оптимизация производительности и ее можно отключить (вполне можно сделать реализацию планировщика корутин, который будет выполнять специально помеченную корутину на том потоке из которого ее вызвали впервые).

В общем мой вывод, что не место реализации корутин от MS в спецификации языка - это нужно сделать либо библиотекой, либо что-то типа OpenMP (на прагмах). А вот нужно в стандарт языка внести то, чего там еще не хватает для реализации переключений контекста на стаках (то, на чем основан Boost::Context). В результате реализацию корутин на переключении стеков можно будет сделать в виде библиотеки (Boost::Corutine действительно выносит мозг и неудобна).

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.