Хотя свойство автоматического обнуления переменной при
инициализации в именованной cOMMON-области было использовано только для
переменной, в которой хранится общая сумма, это свойство можно было бы
использовать и для переменной, хранящей значение флага. Это позволило бы
программе в начале каждого запуска проверять значение переменной-флага и
выполнять начальную последовательность команд только при нулевом значении флага
с последующей заменой его на ненулевое значение. (Если бы это было известно
заранее, можно было бы избавиться от специальной дуги d03, с некоторой, однако,
потерей управления во время выполнения программы.)
Аннотированный листинг
программы
1 с
2 с - Work
Distribution
Распределитель работ
3 с - Sends work
Intervals to workers and flag to summer
Рассылает обрабатываемые
интервалы рабочим процессам
А г и флаг суммирующему
процессу
5 REAL*4 LO,
HI, SIZINTRVL
6 INTEGER
NSEGNENTS, INTRVLS, PASS, WORKER
7 INTEGER*2
FLAG, NWORKERS, TOTINTRVLS, NPASSES, SIZE
Все переменные, которые принимаются
с терминала (с помощью flp) или с константных дуг, должны быть описаны как
INTEGER*2 (см. строку 7).
8 COMMON /TERMIN/ NPASSES, TOTINTRVLS
9 COMMON
/WORKARC/ LO, HI, INTRVLS
Переменные помещаются в COMMON-область в строках 8
и 9 для размещения их в последовательных ячейках памяти. Это необходимо для
чтения и записи по одной дуге более одного значения. В этом случае можно
считать, что определены две записи, каждая в своей COMMON-области, хотя они
могли бы быть определены и в одной COMMON-области с тем же эффектом.
10 CALL
FL0READ(1, NWORKERS, 1, SIZE)
11 CALL FLOREAD(2, NPASSES, 2, SIZE)
Вызов
подпрограммы FLOREAD в строке 10 обеспечивает чтение данных из первой входной
дуги из списка (в записи на языке DGL) входных дуг этого процесса, что указывает
первый параметр обращения к этой подпрограмме (1). В данном случае это
константная дуга, поэтому всегда считывается значение, равное 2. Заметим, что
для этой константной дуги переменная, в которую помещается считанное значение
(NW0RKER), должна быть определена как 1NTEGER*2, а число считываемых слов -
третий параметр обращения - равно 1. Вызов подпрограммы FLOREAD в строке 11
производит чтение данных из второй входной дуги, определенной в DGL
(dOOJntjpass), что задается первым параметром обращения. Эта дуга не связана ни
с каким процессом (согласно записи на DGL), поэтому данные на этой дуге могут
появиться только из какого-либо аппаратного устройства или, как в данном случае,
из терминала, выполняющего программу f 1р. Так как flp может посылать только
однословные (16 битовые) значения, и так как это обращение к подпрограмме
считывает два слова (на что указывает третий аргумент), будет считано два
значения типа INTEGER*2. Первое значение будет помещено в переменную NPASSES, а
второе - в переменную, размещенную в памяти сразу за переменной NPASSES. В
данном случае, так как переменная TOTINTRVLS следует за переменной NPASSES в
блоке COMMON, гарантируется их последовательное размещение в памяти и помещение
второго значения, посланного flp по этой дуге, именно в эту переменную
(TOTINTRVLS).
12 CALL PRINTF(" INTRVLS « Xd npasses « Xd nworkers *
%d\n"f
13 1 TOTINTRVLS. NPASSES. NWORKERS)
Обращением к подпрограмме
PRINTF в строках 12 - 13 производится вывод на терминал, но только в случае,
если на терминале выполняется программа flp, которая была инициирована с опцией
-г. Для тех, кто не знаком с функцией printf языка программирования Си, поясним,
что при ее выполнении производится печать первого параметра обращения к ней
(строки символов), при этом выполняются следующие подстановки:
• Замещаемые
последовательности (которые начинаются с символа %) заменяются значением
следующего аргумента из списка аргументов. При этом буква, следующая за %,
определяет тип значения подстановки. В данном случае, Xd определяет десятичный
формат значения типа INTEGER*2.
• Управляющие последовательности
(представляемые обратным слэшом (\) и следующим за ним символом) заменяются
специальным (обычно неизображаемым) управляющим символом. В данном случае \п
замещается управляющим символом "новая строка" (что определяет при выводе
перевод на следующую строку и возврат каретки, то есть печать следующих символов
начнется с начала новой строки).
14 NSEGMENTS « NPASSES * NWORKERS
15
INTRVLS * TOTINTRVLS
16 SIZINTRVLS = 1.0 / NSEGMENTS
17 HI * 0
18 DO
100 PASS * 1, NPASSES
19 DO 90 WORKER = 1, NWORKERS
20 L0 * HI
21 HI *
HI + SIZINTRVLS
22 CALL FL0WRITE(WORKER. L0, 6)
23
90 CONTINUE
Вызов FL0WRITE в строке
22 помещает 6 слов (12 байт), начиная с переменной L0, в выходную дугу,
определенную переменной WORKER. L0 занимает только 4 байт, a HI (4 байт) и
SIZINTRVL (4 байт) следуют за ней, так как они определены в одном cOMMON-блоке.
Таким образом, посылается предписание на работу (work order) рабочим процессам.
Заметим, что переменная WORKER должна быть определена как переменная типа
INTEGERM, так как она используется в качестве первого аргумента обращения к
FL0WRITE (или к FLOREAD).