Приведем пример некоторой ситуации, где сопрограммы могут оказаться полезными. Вам предлагается напечатать последовательность действительных чисел в качестве ввода, но каждое восьмое число в выводе нужно опустить. Вывод должен представлять собой последовательность строк из шести чисел (кроме последней строки, если для ее заполнения чисел не хватает). Если in обозначает n-й элемент ввода, вывод выглядит так:
i1 i2 i3 i4 i5 i6 i7 i9 i10 i11 i12 i13 i14 i15 i17 и т. д.Наконец, вывод должен включать только 1000 чисел.
Эта задача характерна для использования сопрограмм. Она включает три процесса, каждый со своей специфической логикой: ввод, где требуется пропускать каждое восьмое число, вывод с ограничением строки до шести чисел, главная программа, где требуется обработать 1000 элементов. Традиционные структуры управления неудобны при сочетании процессов с разными ограничениями. Решение, основанное на сопрограммах, будет проходить гладко.
Введем три сопрограммы: producer (ввод), printer (вывод) и controller. Общая структура такова:
begin class PRODUCER begin ... См. далее ... end PRODUCER; class PRINTER begin ... См. далее ... end PRINTER; class CONTROLLER begin ... См. далее ... end CONTROLLER; ref (PRODUCER) producer; ref (PRINTER) printer; ref (CONTROLLER) controller; producer :- new PRODUCER; printer :- new PRINTER; controller :- new CONTROLLER; resume controller endЭто главная программа, в обычном смысле этого слова. Она создает экземпляр каждого из трех классов - соответствующую сопрограмму и продолжает одну из них - контроллер. Классы приведены далее:
class CONTROLLER; begin integer i; detach; for i := 1 step 1 until 1000 do resume printer end CONTROLLER; class PRINTER; begin integer i; detach; while true do for i := 1 step 1 until 8 do begin resume producer; outreal (producer.last_input); resume controller end; next_line end end PRINTER; class PRODUCER; begin integer i; real last_input, discarded; detach; while true do begin for i := 1 step 1 until 6 do begin last_input := inreal; resume printer end; discarded := inreal end end PRODUCER;Тело каждого класса начинается с detach, что позволяет главной программе продолжать инициализацию других сопрограмм.