![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
В следующей версии boost будет включена библиотека coroutine. Прочитав описания стало понятно, как ее использовать, и как она работает. Но для меня пока остается загадкой ответ на вопрос: А ЗАЧЕМ? Единственное, что я могу предположить - деление больших неделимых операций на несколько маленьких. И это все? Может еще зачем-то она нужна и мне это позарез необходимо, но я не понимаю?
Одно точно я вижу, структура программы, использующей ее, значительно усложнится. И без внятной документации понять принцип работы программы будет ой как затруднительно. Подобное происходит, например, с asio. Но там хоть понятно - поставил задачу, до нее дошла очередь, она выполнилась. А тут? Работаешь, сохранил контекст, прыгнул (восстановил другой контекст) в середину другой функции, поработал, прыгнул в середину третьей... ![]() |
|||
|
||||
NoviceF |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
фанаты goto давно ждали возможности для реванша
![]() |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
![]() Реванш слишком жестокий... Кстати, хочется услышать мнение boostcoder на этот счет - он сильно радовался этой либе. |
|||
|
||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 17 Всего: 110 |
если не злоупотреблять, штука довольно полезная
как минимум удобно при обработке последовательностей, при конвертации всяких данных, в некоторых алгоритмах (особенно тех, которые являются комбинацией нескольких сложных кусков) представим себе, что у нас есть последовательность 123456789101112131415... (цифры всех чисел записаны друг за другом), нужно посчитать сумму всех элементов на чётных местах до 1000-го. вывести символы последовательности одним циклом по номеру числа - проще простого, посчитать искомую сумму другим циклом по номеру символа - ещё проще проблемы: 1. предварительно считать может будть накладно по памяти 2. далеко не для всех алгоритмов можно заранее сказать, сколько понадобится элементов без запуска алгоритма самый простой выход - объединить два куска кода, т.е. вместо закидывания во временное хранилище мы просто отбрасываем нечётные, а чётные складываем проблемы: 1. для одного алгоритма естественен цикл по числам, для второго - по символам, что бы мы ни выбрали, код одного из них станет сложнее 2. переменые, отвечающие за состояния алгоритмов (аккумулятор, номер числа) доступны обоим алгоритмам 3. алгоритм генерации последовательности и вычисления искомого значения, по-хорошему, не должны знать ничего друг о друге, тогда легче станет менять последовательности и вычисления независимо 4. плохо масштабируется (ведь может быть целая цепочка преобразований последовательностей) следующий выход - сконвертировать один из алгоритмов во что-то вроде функтора и дёргать его из другого, пример (не для вышеописанной задачи) - std::istream_iterator и какой-нибудь алгоритм из namespace std, можно даже и то, и то, оставив главный цикл одиноким в своей функции (std::istream_iterator, std::find_if, функтор для отсева) в принципе, этот вариант решает все проблемы, но получается довольно-таки неудобным, например , генерировать последовательность, описанную в начале, по одному символу неудобно - нужно больше переменных состояния, код сложнее, да и производительность похуже, с вычислением суммы тоже нужна дополнительная переменная появляется а в случае с coroutines что построение последовательности, что вычисление искомой суммы представляются обычными циклами, циклы эти находятся в разных функциях, друг о друге почти ничего не знают, переменные состояния скрыты, всё хорошо P.S. с Boost.Coroutines я не работал, подробностей не знаю, описывал общее понятие coroutines -------------------- qqq |
|||
|
||||
EvilsInterrupt |
|
|||
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: 2 Всего: 9 |
maxim1000,
Если не сложно, то можно еще один пример где пригодится эта новая фича? Я привык понимать на нескольких. |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
я дал слово, не использовать этот форум по назначению. так, некоторые свои темы буду обновлять. зы на самом деле, в связи с беспределом администрации сего ресурса(от чем я неоднократно писал тут), мне множество раз предлагали сменить ресурс, многие из тех кто еще недавно пользовался этим форумом и перестали. |
|||
|
||||
NoviceF |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
![]() |
|||
|
||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 17 Всего: 110 |
хм... ну например, вот: есть у нас какая-то древовидная структура из каких-то объектов у каждого объекта есть цвет нам нужно пробежаться по объектам и последовательность цветов запаковать как-нибудь (то ли RLE, то ли Zip) самая простая пробежка по дереву - рекурсивная для запаковки, как правило удобно просто бежать циклом по входному потоку coroutines позволяют запихнуть пробежку по дереву в отдельную функцию и выдавать по одному значению, а запаковку - в другую, с простым циклом по значениям -------------------- qqq |
|||
|
||||
Pfailed |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 933 Регистрация: 19.7.2009 Репутация: нет Всего: 39 |
Сопрограммы можно эффективно использовать в сетевом программировании. Предположим в одной функции вы произвели неблокирующий connect, следующая операция в этой функции -- запись в приконнекченный сокет. Естественно пока сокет не законнектится записывать бессмысленно, соответственно имеет смысл на это время переключиться в другую функцию и выполнить другое полезное действие. Таким образом получаем эффективное приложение и все в рамках одного процесса и потока.
|
|||
|
||||
EvilsInterrupt |
|
|||
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: 2 Всего: 9 |
Очень похоже на yeld в генераторах Python и др. современных скриптовых языках. |
|||
|
||||
baldina |
|
||||||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
с точностью до наоборот. вы слишком вникаете в технику исполнения, а следует думать концептуально. технически: сопрограмма имеет состояние, в которое возвращается при каждом последующем вызове. вызов завершается "оператором" возврата yield да. можно сказать, что сопрограммы реализуют yield, а остальное вытекает из этого факта. точно также можно сказать, что сопрограммы имеют состояние и множество точек входа, из которых конкретная определяется состоянием. из этого вытекает возможность реализации yield. сопрограммы - всего лишь инструмент, без него можно жить, но есть ситуации, когда использование сопрограмм дает более короткие и ясные программы. обычно выделяют три ситуации: 1. конечные автоматы. здесь польза прямо вытекает из определения: сопрограмма меняет состояния автоматически, без привлечения специальных механизмов. пример: для реализации автомата, который безусловно переходит в состояния 1->2->3 достаточно написать функцию-сопрограмму
в boost::coroutine все не так лаконично
но идея ясна; это значительно экономичнее и прозрачнее конструкции
а если надо иметь несколько контекстов, вместо static int state потребуется целый огород. 2. генераторы. функции, генерирующие последовательность. возвращаемое значение можно интерпретировать как итератор.
в boost::coroutine и с итераторами:
немного похоже на fsm, правда? действително, fsm - обобщение генераторов в С++ без сопрограмм в простейшем случае нужно поддерживать контейнер для исходящих значений либо лишние параметры, в более сложном - слишкоммногабукф 3. модель взаимодействия акторов (actors). похоже на взаимодействие объектов в ООП (посылкой сообщений\вызовом методов), но отличается независимостью взаимодействующих единиц (вплоть до их параллельного исполнения). это модель типа источник/приемник (producer/consumer), ближайшая аналогия - межсетевое взаимодействие (по протоколу). т.к. акторы (actors) являются сопрограммами, каждая может "думать" в удобных ей единицах: пакетах, запросах и т.п.. это как раз тот пример, который привел maxim1000. более классический пример - взаимодействие лексического и синтаксического анализатора: каждый является функцией, они исполняются параллельно, но у каждого свои "вехи": лексическому анализатору удобно мыслить в терминах лексем, синтаксическому - в терминах конструкций. Это сообщение отредактировал(а) baldina - 8.1.2013, 01:27 |
||||||||||||||
|
|||||||||||||||
volatile |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
baldina, все замечательно, только ваши примеры делают не то что написано, если я не ошибаюсь конечно.
Это же не генератор факториалов, а генератор квадратов, или что-то типа того...
И это тоже не генератор факториалов. ген. факториалов будет как-то так:
Извините что вмешиваюсь, но примеры сбивают с толку просто. Это сообщение отредактировал(а) volatile - 8.1.2013, 00:10 |
||||
|
|||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Исправь, это же типичное UB.
В целом, я пока не проникся... Что-то гложат меня сомнения об эффективности смены контекста (значений всех регистров) по сравнению с вызовом функции (которая может быть встроена, если компилятор это посчитает разумным). Работа с потоками уже, вроде, решена в ASIO. По сути, там тоже самое, только через вызовы функций. Хотя, может в случае парсеров все несколько иначе - я ими не особо занимался. Проблема генераторов решается путем выноса их контекста за пределы функций (типичный класс), причем, это будет эффективнее сопрограмм - нет восстановлений регистров процессора. Я неправ? |
|||
|
||||
baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
да. был пьян, поторопился))) ну, суть ясна, я думаю Добавлено через 13 минут и 51 секунду bsa, все это так.
еще раз повторю: дело не в низкоуровневой реализации, а в высокоуровневной интерпретации, в подходе. это парадигма. ясно, что контекст можно обернуть в класс, можно передать в качестве параметра. вопрос не в том, как реализовать фичу, а как реализовать удобным образом. как я понимаю, yield это часть концепции функционального подхода (и хотя в явном виде далеко не во всех функциональных языках присутствует, три описанные ситуации так или иначе в функциональных языках обычно реализуемы). сопрограммы естественно реализуемы на ассемблере (как это описано у Кнута), а в языках, где есть лишь подпрограммы, реализация требует известных ухищрений. можно использовать или не использовать ООП, обобщенное программирование. можно обойтись без мультиметодов, сравнения с образцом, делегатов и лямбда-функций и т.д. Однако имея эти средства, можно что-то делать яснее и короче. Только и всего. с точки зрения реализации самый простой пример преимущества сопрограмм - возможность отказа от switch в тех ситуациях, когда его нельзя заменить на полиморфизм. |
|||
|
||||
baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
м-да, с примерами не очень. исправил
![]() Добавлено через 7 минут и 32 секунды
bsa, мне даже неловко вам говорить о преждевременной оптимизации... но вообще говоря, любое высокоуровневое решение может повлечь дополнительные накладные расходы. при этом (часто незначительный, по сути) проигрыш в производительности компенсируется выигрышем в затратах на разработку и сопровождение. в примерах Кнута (на MIXе) накладных расходов нет вообще: сопрограмма отличается от подпрограммы лишь тем, что адрес возврата, помещаемый в стек, всегда разный. |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
честно говоря, пока я не прочитал еще раз документацию, я не мог понять, как работает генератор из твоего примера. Не уверен, что эта фича упростит понимание программы. Чтобы ее понимать, нужно знать о ней. |
|||
|
||||
baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
![]() что такое массив и список, чем они похожи и отличаются, где они хороши и плохи и т.д. должен знать каждый. так? что такое подпрограммы - тем более. про сопрограммы - из того же разряда. если бы вопрос крутился не вокруг библиотеки С++, а вокруг языка, непосредственно поддерживающего сопрограммы, вопроса скорее всего просто не возникло бы. bsa, пока не прочитать про ООП, программисту С непонятно что такое класс, как оно работает и т.п. тут то же самое. я отнюдь не хвалю boost::coroutine и не агитирую за испольование сопрограмм. да и примеры, согласен, лучше специально подготовленные, а не на коленке. но тогда уж надо открывать учебники и читать про концепции, преимущества и пр. в книгах это всегда полнее, чем любой ответ на форуме. |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
baldina, думаю ты согласишься с утверждением, что хороший язык программирования отличается от плохого помимо всего прочего ясностью кода. Действия break, return, continue, do, while, if, else и goto вполне очевидны. А вот yield... Ну ладно.
Я понял, что существуют задачи, где использование сопрограмм имеет смысл. Другое дело, что я таких не припомню. |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
baldina, Еще раз извиняюсь за занудство, исправьте уж нормально, а то теперь у вас генератор нулей получился. bsa, ну это как рекурсия. любую задачу можно решить без нее, согласитесь. Но встречаются задачи (изредка) которые с рекурсией получаются гораздо короче и понятней. С этим точно также. |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
volatile, я не спорю.
|
|||
|
||||
chaos |
|
|||
![]() Серийный программист ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2979 Регистрация: 7.7.2004 Где: Екатеринбург Репутация: 6 Всего: 44 |
Чото нифига пока понять не могу.
Вопрос по первому же рисунку из доки ![]() Что нужно написать в main что бы получить такой же оутпут? |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Там речь идет о том, как такое сделать.
|
|||
|
||||
EvilsInterrupt |
|
|||
Executables research ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1019 Регистрация: 14.7.2007 Где: Железнодорожный, МО, Россия Репутация: 2 Всего: 9 |
Может кому-то пригодится. Для чего и зачем применять сопрограммы(coroutine). На мой взгляд достаточно лаконично и понятно описано в справочнике по Python Девид Бизли 4. изд. 2010 г.
Пояснения : стр.136 - Замыкания, декораторы, генераторы, сопрограммы Примеры использования: стр.146(генераторами), стр.42, стр.147 (сопрограммы) |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |