Здравствуйте, LaptevVV, Вы писали:
LVV>А в каких задачах корутины вот прям супер — супер? LVV>Чего раньше приходилось делать муторно и долго ?
Вообще изначально это рекурсивный обход деревьев.
То есть после каждого MoveNext мы должны запомнить состояние для следующего MoveNext.
На этом Linq в .Net работает и async/await
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, rg45, Вы писали: R>Это что за "тут играйте, тут не играйте"?. Не-не-не, давай по-чесноку. Я тебе давал полный текст программы и ты давай тоже полный. Вместо со "вспомогательными макросами" и ссылкой на запускаемую программу.
На самом деле С++20 корутины имеют внутри что-то похожее, но на уровне компилятора. Но стандартные корутины также реализуют автоматическое сохранение всех переменных, используемых внутри корутины, что в случае switch..case на стероидах приходится делать вручную.
Здравствуйте, so5team, Вы писали:
L>>С высоты своего опыта могу заявить, что "иерархические КА", "вложенные состояния" и прочая дичь есть не более чем словесный онанизм от теоретиков, которые даже не пытались перейти от словесного описания к реализации в коде.
S>Очередной Д`Артаньян в белом пОльто и с членом такой длины, что волочится по асфальту, детектед.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, kov_serg, Вы писали:
R>Жульничаешь? Изюм выковыриваешь? Ну, я помогу тебе сделать этот нелёгкий шаг. Сравни следующие два варианта:
Нет. Вся обвеска делается вспомогательными функциями. Макросы нужны чтобы упростить написание.
Более того он позволяет единообразно производить декомпозицию асинхронных операций.
Кроме того он не запрещает использовать и корутины если они поддерживаются компилятором.
R>И что, тебе реально твой вариант больше нравится? Лично я бы не выбрал этот вариант из-за одних только "вспомогательных макросов". Ну и вообще...
Да. Т.к. он значительно проще, понятнее, всё под полным контролем. Никаких скрытых или недоступных состояний.
Я могу сохранять состояние на диск или передать по сети и потом возобновлять на другой машине.
И он работает даже на микроконтроллерах с десятками байт RAM где есть тольк C компилятор.
Здравствуйте, rg45, Вы писали:
R>И что, тебе реально твой вариант больше нравится? Лично я бы не выбрал этот вариант из-за одних только "вспомогательных макросов". Ну и вообще...
Stackless корутины из asio прячут все эти "вспомогательные макросы".
Но нужно быть очень осторожным в коде таких "корутин" — неосмотрительное применение switch..case и все разваливается с кучей спецэффектов.
Также, все переменные контекста корутины нужно где-то вручную сохранять. Боль моя дырка задница.
Мы их, впрочем, успешно использовали для реализации развесистой асинхронной логики в отсутствие 20-х корутин. Грубо говоря, пришлось применить именно их, т.к. стековые корутины не подошли из-за оверхеда на переключение и памяти для стеков.
Здравствуйте, kov_serg, Вы писали:
R>>Жульничаешь? Изюм выковыриваешь? Ну, я помогу тебе сделать этот нелёгкий шаг. Сравни следующие два варианта: _>Нет. Вся обвеска делается вспомогательными функциями. Макросы нужны чтобы упростить написание. _>Более того он позволяет единообразно производить декомпозицию асинхронных операций. _>Кроме того он не запрещает использовать и корутины если они поддерживаются компилятором.
R>>И что, тебе реально твой вариант больше нравится? Лично я бы не выбрал этот вариант из-за одних только "вспомогательных макросов". Ну и вообще... _>Да. Т.к. он значительно проще, понятнее, всё под полным контролем. Никаких скрытых или недоступных состояний. _>Я могу сохранять состояние на диск или передать по сети и потом возобновлять на другой машине. _>И он работает даже на микроконтроллерах с десятками байт RAM где есть тольк C компилятор.
Ну, мне остаётся только пожелать тебе творческих успехов.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, landerhigh, Вы писали:
L>Где-то я это видел
L>На самом деле С++20 корутины имеют внутри что-то похожее, но на уровне компилятора. Но стандартные корутины также реализуют автоматическое сохранение всех переменных, используемых внутри корутины, что в случае switch..case на стероидах приходится делать вручную.
Зато есть полный контроль над происходящим. Более того основная засада не в корутинах, а в их диспечеризации.
Здравствуйте, landerhigh, Вы писали:
L>Stackless корутины из asio прячут все эти "вспомогательные макросы". L>Но нужно быть очень осторожным в коде таких "корутин" — неосмотрительное применение switch..case и все разваливается с кучей спецэффектов. L>Также, все переменные контекста корутины нужно где-то вручную сохранять. Боль моя дырка задница. L>Мы их, впрочем, успешно использовали для реализации развесистой асинхронной логики в отсутствие 20-х корутин. Грубо говоря, пришлось применить именно их, т.к. стековые корутины не подошли из-за оверхеда на переключение и памяти для стеков.
Да я в курсе. По этим граблям я тоже хаживал
Более того, где-то в конце 90-х или начале 2000-х я сам мастырил свой собственный механизм stack-full корутин поверх longjmp.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали: R>Более того, где-то в конце 90-х или начале 2000-х я сам мастырил свой собственный механизм stack-full корутин поверх longjmp.
Здравствуйте, landerhigh, Вы писали:
L>Здравствуйте, kov_serg, Вы писали:
_>>Зато есть полный контроль над происходящим.
L>Это до тех пор, пока (не "если", а "пока") кто-то в коде такой "корутины вручную" не напишет. L>
L>Нет, рано или поздно ошибка найдется, но все равно, happy debugging!
Тут всё же предполагается некотарая дисциплина, для соблюдения ряда требований. Да и компилятор уматерит. Что инициализация не в своём скоупе.
typedef struct {
int loop;
int machineID, *param;
const char* value;
unsigned int i;
} fn1_t;
void fn1_setup(fn1_t *self) { self->loop=0; }
int fn1_loop(fn1_t *self) {
LOOP_BEGIN(self->loop)
self->value="Idle"; LOOP_POINT
self->value="Started"; LOOP_POINT
for ( self->i = 0; self->i<10 && !connected(); ++self->i )
{
connect(); LOOP_POINT
}
self->value="Processing"; LOOP_POINT
while (*self->param < 10) {
self->value="Waiting"; LOOP_POINT
}
self->value="Stopped";
LOOP_END
}
L>Диспетчерезация обычно определяется собственно уровнем I/O, и как правило сводится к вызову корутины из колбека.
Вот тут одна из засад, колбэки не гарантируют их какого потока будут вызваны.
Здравствуйте, kov_serg, Вы писали:
_>Тут всё же предполагается некотарая дисциплина, для соблюдения ряда требований.
Требуется в первую очередь понимание, что внутри этой функции много чего нельзя из того, что во всех других местах можно. Когда код уехал другом разработчику, с этим может оказаться сложно.
_>Да и компилятор уматерит. Что инициализация не в своём скоупе.
Так, надо попробовать, даже интересно стало.
L>>Диспетчерезация обычно определяется собственно уровнем I/O, и как правило сводится к вызову корутины из колбека. _>Вот тут одна из засад, колбэки не гарантируют их какого потока будут вызваны.
С точки зрения корутины это вовсе не обязательно минус. Воможность "разбудить" корутину в другом потоке может быть большим плюсом.
Опять же, проблемы диспетчерезации ортогональны корутинам.
Здравствуйте, rg45, Вы писали:
R>На всякий случай вдогонку: R>Правило №16. Избегайте макросов R>Мало ли, вдруг надумаешь С++ изучать.
На всякий случай: Это лишь рекомендации. Если бы комитет не употреблял тяжелые наркотики уже бы добавили нормальные макросы в язык. А пока приходится использовать то что есть.
Здравствуйте, landerhigh, Вы писали:
_>>Тут всё же предполагается некотарая дисциплина, для соблюдения ряда требований.
L>Требуется в первую очередь понимание, что внутри этой функции много чего нельзя из того, что во всех других местах можно. Когда код уехал другом разработчику, с этим может оказаться сложно.
Так во моногих местах можно делать не всё что угодно. И ничего живём как-то.