Pull to refresh

Comments 3

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

Я как-то написал аналогичную систему сопрограмм для C++, но со следующими отличиями:

1. Вместо потоков использовал Fiber (Windows) и getcontext (Linux). В моём случае было именно много легковесных сопрограмм, работающих с сетью, поэтому использование потоков было неуместно.

2. Для работы с сокетами использовал неблокирующие вызовы и epoll, вызываемый собственным планировщиком.

Недостатки же были следующие: сложность отладки и высокое потребление памяти. Смена контекста полностью прятала сопрограмму для отладчика. А память потреблял независимый стек каждой из сопрограмм.

А затем я на всё это плюнул и перешёл на язык со встроенной реализацией сопрограмм в виде машин состояния. При этом переписал встроенный планировщик и операции с сокетами для достижения максимальной масштабируемости, а именно: принудительный однопоточный режим вместо использования пула потоков и epoll для ожидания дескрипторов вместо колбэков на пуле потоков.

Писал тут игру недавно на C++ CX (да, windows-specific) но зато для корутин блестящее/удобное ключевое слово co_await (аналог async/await в C# быть может когда-нибудь будет в стандарте :):


task<void> PlayScript()
{
        co_await Delay(1f); // подождать 1 секунду игрового времени
        text_->SetText("start");
        // повернуть узел на 90 градусов за 1 секунду игрового времени
        co_await Rotate(1f, boxNode_, Quaternion(0, 90, 0)); 
        boxNode_->SetScale(1f);
        // изменить масштаб узла за 1 секунду и.в.
        co_await ScaleBy(1f, boxNode_, Vector3(2, 2, 2));
        text_->SetText("End");
}

В этом коде не создается дополнительных поток и нет блокировок/слипов :-)

Поправьте, если я ошибаюсь, но вы же просто плодите потоки. По крайней мере, меня в этом убеждает std::make_unique в конструкторе Coroutine, и не похоже, чтобы они шарились внутри CoroutineSet. И получается, что вы замысловато обернули потоки, что, согласитесь, не совсем отражает суть сопрограмм.
Во избежание срачей, да, я понимаю, что сопрограммы можно симулировать через потоки, но это, всё-таки, не эквивалентные понятия.

Я ожидал всё-таки какого-нибуть хитрого класса Coroute со стеком функций и их входных параметров и методом\макросом yield. Ну или, хотя бы, красиво обёрнутые списки задач, с функторами и лямбдами-транзакциями. Который будет жить в одном потоке с вызывающим потоком, делить плоть и кровь, что называется…
Sign up to leave a comment.