vak: (Default)
[personal profile] vak
Давайте изобразим на сопрограммах тривиальный симулятор. Пусть у нас есть класс simulator_t, его реализующий.

Добавим модельное время: целое число, монотонно увеличивающееся по мере выполнения. Пусть метод simulator_t::time() возвращает это время. Другой метод simulator_t::delay(N) пусть приостанавливает текущий процесс на указанное число тактов.

Моделируемые процессы будем представлять в виде отдельных независимых сопрограмм. В начале мы создаём эти процессы посредством метода simulator_t::make_process(), затем запускаем симуляцию методом simulator_t::run().

Вот так выглядит главная программа:
int main()
{
simulator_t sim;
sim.make_process("clock", clock);
sim.make_process("master", master);
sim.run();
}
Первый процесс - условный генератор синхросигнала. Через каждую единицу времени он изменяет значение сигнала Clock с 0 на 1 и наоборот. Сам сигнал добавим позже, в следующем посте, а пока просто печатаем строчку. Задержка реализуется оператором "co_await sim.delay(N)".
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);
}
}
Второй процесс как бы наблюдает за выполнением и завершает симуляцию через 10 единиц времени:
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
This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org