Давайте изобразим на сопрограммах тривиальный симулятор. Пусть у нас есть класс simulator_t, его реализующий.
Добавим модельное время: целое число, монотонно увеличивающееся по мере выполнения. Пусть метод simulator_t::time() возвращает это время. Другой метод simulator_t::delay(N) пусть приостанавливает текущий процесс на указанное число тактов.
Моделируемые процессы будем представлять в виде отдельных независимых сопрограмм. В начале мы создаём эти процессы посредством метода simulator_t::make_process(), затем запускаем симуляцию методом simulator_t::run().
Вот так выглядит главная программа:
Исходники можно глянуть здесь: https://github.com/sergev/simulation-with-coroutines
Добавим модельное время: целое число, монотонно увеличивающееся по мере выполнения. Пусть метод simulator_t::time() возвращает это время. Другой метод simulator_t::delay(N) пусть приостанавливает текущий процесс на указанное число тактов.
Моделируемые процессы будем представлять в виде отдельных независимых сопрограмм. В начале мы создаём эти процессы посредством метода simulator_t::make_process(), затем запускаем симуляцию методом simulator_t::run().
Вот так выглядит главная программа:
Первый процесс - условный генератор синхросигнала. Через каждую единицу времени он изменяет значение сигнала Clock с 0 на 1 и наоборот. Сам сигнал добавим позже, в следующем посте, а пока просто печатаем строчку. Задержка реализуется оператором "co_await sim.delay(N)".int main()
{
simulator_t sim;
sim.make_process("clock", clock);
sim.make_process("master", master);
sim.run();
}
Второй процесс как бы наблюдает за выполнением и завершает симуляцию через 10 единиц времени:co_void_t clock(simulator_t &sim)
{
for (;;) {
std::cout << '(' << sim.time() << ") Clock set" << std::endl;
co_await sim.delay(1);
std::cout << '(' << sim.time() << ") Clock reset" << std::endl;
co_await sim.delay(1);
}
}
Компилируем и запускаем:co_void_t master(simulator_t &sim)
{
std::cout << '(' << sim.time() << ") Started" << std::endl;
co_await sim.delay(5);
std::cout << '(' << sim.time() << ") Half way through" << std::endl;
co_await sim.delay(5);
std::cout << '(' << sim.time() << ") Finished" << std::endl;
sim.finish();
}
Как мы можем видеть, симулятор выполняет эти две сопрограммы как бы параллельно, переключаясь между ними при необходимости по мере продвижения модельного времени.$ make
g++-10 -std=c++20 -fcoroutines -c -o demo1.o demo1.cpp
g++-10 -std=c++20 -fcoroutines -c -o simulator.o simulator.cpp
g++-10 -std=c++20 -fcoroutines demo1.o simulator.o -o demo1
$ ./demo1
(0) Started
(0) Clock set
(1) Clock reset
(2) Clock set
(3) Clock reset
(4) Clock set
(5) Half way through
(5) Clock reset
(6) Clock set
(7) Clock reset
(8) Clock set
(9) Clock reset
(10) Finished
Исходники можно глянуть здесь: https://github.com/sergev/simulation-with-coroutines
