Прелесть энумератора в том, что при вычеслении цепочки по MoveNext вычисление идет справа на лево. То есть обход начальной коллекции будет только 1 раз
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, LaptevVV, Вы писали:
LVV>А в каких задачах корутины вот прям супер — супер? LVV>Чего раньше приходилось делать муторно и долго ?
Очевидно для ассинхронности. Сейчас ассинхронность можно реализовасть либо плодя кучу потоков, либо с помощью коллбеков.
Плодить потоки нееээфетивно, да и отлаживать многопоточный код, то еще удовольствие.
А если использовать коллбэки, если задача совсем тривиальная, и надо помнить состояние то код становится совершенно нечитаемым (так назваемый callback hell).
Корутины, это синтаксический сахар, позволяющий написать код, красивоо и линейно, вместо того, чтобы использовать коллбеки и постоянно передовать между ними контекст.
В первую очередь, где явно видно это преимущество, это работа с сетью. Например, у нас есть некий сервер, на который приходит запрос, получив этот запрос, чтобы обработать запрос, мы должны отправить еще несколько запросов, в разные базы данных которые крутятся на других серверах, и сформировать итоговый ответ, по результатам того, что пришло из баз. Корутина позволяет сделать это красиво и не плодить потоки.
Здравствуйте, LaptevVV, Вы писали:
LVV>А в каких задачах корутины вот прям супер — супер? LVV>Чего раньше приходилось делать муторно и долго ?
Генераторы в питоне для создания итераторов сильно проще чем интерфейс руками писать, нет?
Тут народ про async/await, но там корутины с concurrency смешаны и увидеть их сложнее.
Здравствуйте, ksandro, Вы писали: K>Корутины, это синтаксический сахар, позволяющий написать код, красивоо и линейно, вместо того, чтобы использовать коллбеки и постоянно передовать между ними контекст.
K>В первую очередь, где явно видно это преимущество, это работа с сетью. Например, у нас есть некий сервер, на который приходит запрос, получив этот запрос, чтобы обработать запрос, мы должны отправить еще несколько запросов, в разные базы данных которые крутятся на других серверах, и сформировать итоговый ответ, по результатам того, что пришло из баз. Корутина позволяет сделать это красиво и не плодить потоки.
Как здесь может помочь корутина, то есть функция, которая может сама возвратиться из середины всли ей надо, но потом продолжить с этого места по сигналу?
Возможно корутина отправляет запрос на базу данных зависает в ожидании ответа? То есть несколько корутин для нескольких БД вызваны по очереди и ждут....
И судя по всему все ответы получает таки основной серверный поток, в нем типа еще один мини сервер который ждет ответы. Если что приходит, то главный поток анализирует откуда пришло и бУдит нужную корутину, передав ей видимо как-то этот ответ БД для обработки? А тогда корутина обрабатывает ответ и что то там генерит на основе его. А главный поток должен сообразить когда все корутины завершились или там после таймаута, выключить свой минисервер для БД, создать итоговый ответ для клиента "некого сервера".
Без корутин. Для каждого запроса создаем новый поток, который все делает сам отправляет запросы на бд, ждет ответ, принимает ответ от БД, и обрабатывает. Тут как бы весь код для БД в одном месте а не разбросан то функциям и корутинам, и новых серверов нет. Тоже надо следить все ли потоки завершились или таймаут настал и потом все данные обработать и отослать.
В чем корутины лучше то? Потоков не создается, так это не проблема в общем в настоящее время. Конечно если запросов ну очень много надо это как-то регулировать.
Но и скорость обработки скорее всего у корутин ниже. Потоки могут одновременно работать а корутины это просто функции. Если одна работает то все остальные созданные основным потоком да и сам основной поток ничего не делают, ждут когда корутина вернет управление.
Здравствуйте, qqqqq, Вы писали:
Q>Здравствуйте, ksandro, Вы писали: K>>Корутины, это синтаксический сахар, позволяющий написать код, красивоо и линейно, вместо того, чтобы использовать коллбеки и постоянно передовать между ними контекст.
K>>В первую очередь, где явно видно это преимущество, это работа с сетью. Например, у нас есть некий сервер, на который приходит запрос, получив этот запрос, чтобы обработать запрос, мы должны отправить еще несколько запросов, в разные базы данных которые крутятся на других серверах, и сформировать итоговый ответ, по результатам того, что пришло из баз. Корутина позволяет сделать это красиво и не плодить потоки.
Q>Как здесь может помочь корутина, то есть функция, которая может сама возвратиться из середины всли ей надо, но потом продолжить с этого места по сигналу?
Q>Возможно корутина отправляет запрос на базу данных зависает в ожидании ответа? То есть несколько корутин для нескольких БД вызваны по очереди и ждут.... Q>И судя по всему все ответы получает таки основной серверный поток, в нем типа еще один мини сервер который ждет ответы. Если что приходит, то главный поток анализирует откуда пришло и бУдит нужную корутину, передав ей видимо как-то этот ответ БД для обработки? А тогда корутина обрабатывает ответ и что то там генерит на основе его. А главный поток должен сообразить когда все корутины завершились или там после таймаута, выключить свой минисервер для БД, создать итоговый ответ для клиента "некого сервера".
Q>Без корутин. Для каждого запроса создаем новый поток, который все делает сам отправляет запросы на бд, ждет ответ, принимает ответ от БД, и обрабатывает. Тут как бы весь код для БД в одном месте а не разбросан то функциям и корутинам, и новых серверов нет. Тоже надо следить все ли потоки завершились или таймаут настал и потом все данные обработать и отослать.
Q>В чем корутины лучше то? Потоков не создается, так это не проблема в общем в настоящее время. Конечно если запросов ну очень много надо это как-то регулировать.
Q>Но и скорость обработки скорее всего у корутин ниже. Потоки могут одновременно работать а корутины это просто функции. Если одна работает то все остальные созданные основным потоком да и сам основной поток ничего не делают, ждут когда корутина вернет управление.
ИМХО Вы не очень хорошо понимаете сути ассинхронности, принципы работы сети и неблокирующих вызовов.
Есть высоконагруженный сервер. К нему каждую секунду поступает 100500 запросов. Если на каждый запрос создавать поток, а затем еще создавать поток для запроса к БД, то сервер будет тратить большую часть ресурсов исключительно на создание/убийство потоков, а так же на их синхронизацию, при этом потоки большую часть времени будут ничего не делать а просто спать ожидая ответа от бд, в итоге мы имеем очень низкую производительность трату огромных ресурсов на ничего не делание. Поэтому уже давно высокопроизводительные сервера работают несколько подругому. На самом деле с сетью работает ядро, да и с дисками работает ядро, и есть специальные системные вызовы, сигнализирующие нам о том, что какой-то в какой-то файл/сокет доступен для чтения/записи (epoll, IOCP). Да нам нужно что-то типа планировщика. В обычной ситуации мы сохраняем контекст запроса, затем можем ожидать или отправлять следующие запросы. Когда пришел ответ, мы вызываем некий коллбэк. Корутина отправляет запрос и возвращается, когда приходит ответ мы в качестве коллбека вызываем ту же самую корутину, и она продолжает работату с того самого места, где мы отправили запрос. То есть внутри корутины все выглядит как синхронная процедура, после запроса мы получаем ответ, и продолжаем работу.
Описал я как-то сумбурно, но вообще это сложно объяснить в двух словах. посмотрите например на примеры работы библиотеки boost asio (https://www.boost.org/doc/libs/latest/doc/html/boost_asio/examples/cpp20_examples.html#boost_asio.examples.cpp20_examples.coroutines) код с корутинами выглядит красивее. Ну и вообще погуглите про написание сетевых программ на базе корутин. Код с корутинами по скорости работает так же как неблокирующий сервер на коллбеках, накладные расходы минимальны, не сравнить с порождением потока на каждый чих. Есть еще стекфул корутины и файберы, тоже интересная штука.
До тех пор пока в отладке не придется разбираться во что превращается каждый co_await, co_return и co_yield.
Из того, что вы описали про "преимущества" stackless-короутин складывается устойчивое ощущение, что все тоже самое было бы еще гораздо проще и удобнее со stackfull-короутинами. Где был бы линейный код без мусорных co_, аналогичный тому, чтобы написали бы "в лоб" на голых нитях, но без оверхэда этих самых голых нитей.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, kov_serg, Вы писали:
_>>А теперь запустите 3 таких машины.
R>Да не вопрос: R>И чо?
R>Теперь асинхронность появилась?
Теперь пусть одна из них постепенно создаст еще 2 асинхронных машины, что бы их было не больше 5 нет лучше 6 штук.
И каждая из них имеет разное кол-во итераций до окончания.
Здравствуйте, kov_serg, Вы писали:
_>Теперь пусть одна из них постепенно создаст еще 2 асинхронных машины, что бы их было не больше 5 нет лучше 6 штук. _>И каждая из них имеет разное кол-во итераций до окончания.
Ну вот тогда уже и появится асинхронность (я ж и не говорил, что это невозможно). Только эта асинхронность будет привнесена программистом, а не являться свойством самих корутин.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, so5team, Вы писали:
S>До тех пор пока в отладке не придется разбираться во что превращается каждый co_await, co_return и co_yield.
И во что он превращается и, главное, зачем с этим нужно разбираться при, гхм, "отладке"?
S>Из того, что вы описали про "преимущества" stackless-короутин складывается устойчивое ощущение, что все тоже самое было бы еще гораздо проще и удобнее со stackfull-короутинами.
На то, что корутины из 20 стандарта бесстековые, тут пока никто внимание особо не обращал. И уж тем более никто не говорил про их преимущества и недостатки перед корутинами стековыми. Просто кое-кому просто захотелось поумничать
S>но без оверхэда этих самых голых нитей.
Оверхед на переключение контекста в случае стековых корутин примерно равен ему же для нитей (порядка 170 инструкций). Плюс память для стека. Удачи запустить 1000 корутин.
R>Ну вот тогда уже и появится асинхронность (я ж и не говорил, что это невозможно). Только эта асинхронность будет привнесена программистом, а не являться свойством самих корутин.
Так асинхронность важна не сама по себе. Её должно быть удобно использовать. Корутины сами по себе не есть асинхронность, просто запись кода.
Асинхронность это правила и гарантии которые этому коду позволят правильно работать.
Здравствуйте, kov_serg, Вы писали:
_>Так асинхронность важна не сама по себе. Её должно быть удобно использовать. Корутины сами по себе не есть асинхронность, просто запись кода. _>Асинхронность это правила и гарантии которые этому коду позволят правильно работать.
Все эти высказывания не вызывают возражений.
Только возникают сомнения в том, что я правильно понимаю предмет дискуссии.
Ты не мог бы сформулировать тезис, который ты доказываешь?
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, landerhigh, Вы писали:
S>>До тех пор пока в отладке не придется разбираться во что превращается каждый co_await, co_return и co_yield.
L>И во что он превращается и, главное, зачем с этим нужно разбираться при, гхм, "отладке"?
В обычную нечитаемую лапшу, надо полагать.
S>>Из того, что вы описали про "преимущества" stackless-короутин складывается устойчивое ощущение, что все тоже самое было бы еще гораздо проще и удобнее со stackfull-короутинами.
L>На то, что корутины из 20 стандарта безстековые, тут пока никто внимание особо не обращал.
Поскольку в C++ короутины только безстековые, то разговаривать можно было только о них.
L>Просто кое-кому просто захотелось поумничать
Кого-то просили привести пример преимущества короутин над КА, но кто-то что-то проигнорировал.
S>>но без оверхэда этих самых голых нитей.
L>Оверхед на переключение контекста в случае стековых корутин примерно равен ему же для нитей (порядка 170 инструкций). Плюс память для стека. Удачи запустить 1000 корутин.
ЕМНИП, яндексовский userver с этой задачей спокойно справляется.
Здравствуйте, rg45, Вы писали:
R>Только возникают сомнения в том, что я правильно понимаю предмет дискуссии.
R>Ты не мог бы сформулировать тезис, который ты доказываешь?
Сами по себе коротиные не решают пробелему асинхронного исполнения, она немного в другой плоскости и не связана с корутинами.
Корутины это просто сопособ записи. Без них можно спокойно писать точно такой же код. При этом достаточно обычного голого C.
Главная засада в планировщие он диктует все правила и гарантии для асинхронного кода.
Например в самом простом случае: real-time коде это обязательство вызывать асинхронный код регулярно (например 1000 раз в сек), а сам код дожен успевать испольнятся (менее чем за 1мс).