3295 СРЕДСТВА ПАРАЛЛЕЛЬНОГО ПРОГРАММИРОВАНИЯ В ЯЗЫКЕ АДА

Лабораторная работа № 5

 

БАЗОВЫЕ СРЕДСТВА ПАРАЛЛЕЛЬНОГО ПРОГРАММИРОВАНИЯ
В ЯЗЫКЕ АДА

Цель работы

Изучение средств программирования языка Ада для описания и синхронизации параллельных процессов: задач, оператора принятия, оператора вызова входа.

Методические указания

  1. Понятие задачи

Средства параллельного программирования важны по двум причинам:

1. Для ускорения обработки информации за счет параллельного  выполнения операций на многопроцессорных системах.

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

При написании программ, имеющих в своем составе параллельные процессы, в языке программирования должны быть особые средства, позволяющие работать с такими процессами. В языке Ада параллельные процессы реализуются с помощью задач.

В языке Ада задача – это конструкция, используемая для определения последовательности действий, которая может выполняться параллельно с другими последовательностями действий. Параллельное выполнение задач понимается в том смысле, что каждая задача выполняется отдельным логическим процессором. Различные задачи (на различных логических процессорах) выполняются независимо, за исключением моментов синхронизации, т. е. когда задачи связываются друг с другом. Параллельное выполнение задач может быть реализовано на многопроцессорной системе или смоделировано путем чередующегося выполнения на единственном физическом процессоре.

Задача может содержать входы. Вход задачи может быть вызван другими задачами. Задача принимает вызов входа путем выполнения оператора принятия этого входа. Синхронизация двух задач происходит посредством рандеву между задачей, вызывающей вход, и задачей, принимающей этот вызов. Входы могут иметь параметры. Операторы вызова входа и операторы принятия входа являются основным средством синхронизации задач и обмена данными между задачами.

2. Спецификация и тело задачи

Свойства каждой задачи определяются соответствующим
задачным модулем, который состоит из спецификации задачи и тела задачи. Задача не может быть откомпилирована самостоятельно. Поэтому для компиляции задача должна быть помещена в подпрограмму или пакет.

Общая форма спецификации задачи:

TASK   имя_задачи   IS

ENTRY  имя_входа_1(формальный_параметр_1: имя_типа_1;

………

формальный_параметр_K: имя_типа_K);

.

.

.

ENTRY  имя_входа_N(формальный_параметр_L: имя_типа_L;                                                     ………

формальный_параметр_M: имя_типа_M);

END   имя_задачи;

Эта форма спецификации определяет задачу со входами, имеющими формальные параметры. К данной задаче могут обращаться другие задачи, вызывая ее входы. Конструкция

ENTRY   имя_входа(формальные параметры);

называется описанием входа. Вход может иметь формальные параметры видов IN (только для чтения),  OUT (только для записи)   или IN  OUT (и для чтения, и для записи). Если вид формального параметра не задан, то по умолчанию принимается вид IN.                 Какой-либо из входов задачи (или даже все входы) может не иметь параметров, тогда его описание выглядит так:

ENTRY    имя_входа;

К такому входу тоже можно обращаться, вызывая его из других задач. Задача может быть вообще без входов. Такую задачу нельзя вызвать другими задачами для выполнения рандеву. Спецификация задачи  без входов имеет  следующую форму:

TASK   имя_задачи;

Примеры спецификаций задач:

TASK    A;          – – спецификация задачи без входов

TASK   B   IS      – – спецификация задачи со входом

ENTRY   X;     – – вход Х не имеет параметров

END   B;

TASK   C   IS      – – спецификация задачи со входом

ENTRY (Y:IN  INTEGER); – – вход D имеет параметр

END C;

Тело задачи имеет вид:

TASK   BODY   имя_задачи   IS

[ раздел описаний ]

BЕGIN

последовательность_операторов

END  имя_задачи;

Раздел описаний является необязательным. Выполнение задачи определяется соответствующим телом задачи.

Пример программы, содержащей задачи:

WITH TEXT_IO; USE TEXT_IO;

PROCEDURE EXAMPLE  IS  – –процедура,содержащая задачи

TASK  A;                       – – спецификация задачи А

TASK  B;                       – – спецификация задачи В

TASK  BODY  A  IS     – – тело задачи А

BEGIN                       – – А

PUT_LINE(“A1”);

PUT_LINE(“A2”);

END A;

TASK  BODY  B  IS  – – тело задачи В

BEGIN                     – – В

PUT_LINE(“B1”);

PUT_LINE(“B2”);

END B;

BEGIN  – – начало последовательности операторов процедуры

– – задачи  А и В становятся активными

NULL; – – пустой оператор

END EXAMPLE;

 

3. Задачные типы

Задачные типы облегчают описание одинаковых задач, т.к. несколько одинаковых задач могут быть описаны вместе в массиве или индивидуально. Спецификация      задачи,    начинающаяся     зарезервированными  словами TASK  TYPE, описывает задачный тип. Например, опишем задачный тип К:

TASK  TYPE   K   IS

ENTRY  P1;

END K;

После описания задачного типа можно описывать объекты этого типа. Значение объекта задачного типа представляет собой задачу, которая имеет те же входы, что и соответствующий задачный тип, и выполнение которой определено соответствующим телом задачи. Например, описание

F1, F2 : K;

определяет две задачи ( два объекта задачного типа ) F1 и F2. Эти задачи становятся активными непосредственно перед выполнением первого оператора подпрограммы или перед выполнением пакета, в котором эти задачи описаны.

Массивы, элементами которых являются задачи, описываются точно так же, как массивы элементов любых других типов. Например, описание

F: ARRAY  (1..5)   OF   K;

определяет массив из пяти задач. Каждый элемент массива F является задачей. Объект задачного типа является константой, т. е. такой объект всегда обозначает одну и ту же задачу.

  1. Состояния задач

Задачи становятся активными (т. е. они начинают свою логически независимую работу, действуя так, как будто бы они выполнялись на различных процессорах), когда в подпрограмме или пакете, которые их содержат, встретится зарезервированное слово BEGIN, следующее за разделом описаний этой подпрограммы или пакета.

Примечание. В общем виде тело процедуры имеет вид:

PROCEDURE  имя_процедуры(формальные_параметры)  IS

раздел_описаний

BEGIN

последовательность_операторов

END  имя_процедуры;

Задачи становятся активными в произвольном порядке. Запуск задачи означает последовательное выполнение операторов из исполняемой части ее тела. Говорят, что задача, блок или подпрограмма закончили выполнение, если все относящиеся к ним операторы были выполнены, т. е. был достигнут конец тела.

Задачи не могут компилироваться самостоятельно. Обычно их помещают в раздел описаний подпрограммы или пакета (см. в п.2 пример процедуры EXAMPLE и ее раздел описаний). Поэтому задача должна находиться в зависимости от некоторого «владельца», который может представлять из себя подпрограмму, пакет, блок или другую задачу. Если задача находится в разделе описаний, например подпрограммы, то эта подпрограмма будет владельцем данной задачи
(в примере в п.2 процедура EXAMPLE является владельцем задач A и B).

Задача завершается, если она:

1)       закончилась и не имеет зависящих от нее задач;

2)       закончилась, а все зависящие от нее задачи завершились;

3)       ожидает открытой альтернативы завершения в операторе отбора и при этом задача зависит от владельца, выполнение которого закончено, и  все зависящие от данного владельца задачи либо завершились,  либо ожидают открытой альтернативы завершения в операторе отбора. (Оператор отбора рассмотрен в лаб. работе № 6).