Описание языка PascalABC.NET - W Cat
Шрифт:
Интервал:
Закладка:
{$omp parallel sections}
begin
секция 1;
секция 2;
...;
end;
Каждый оператор в блоке begin ... end, следующем за директивой является отдельной секцией.
{$omp parallel sections}
begin
оператор 1;
оператор 2;
begin
оператор 3;
оператор 4;
оператор 5;
end;
end;
Здесь описаны три параллельные секции, первая – оператор 1, вторая – оператор 2 и третья – блок begin ... end, состоящий из операторов 3-5.
Все переменные, описанные вне параллельных секций, будут разделяемыми, то есть, если в секциях есть обращение к таким переменным, то потоки, выполняющие эти секции, будут обращаться к одной и той же ячейке памяти. Все переменные, объявленные внутри секции, будут доступны только в той секции, в которой они объявлены.
Корректная работа параллельных секций возможна, только если секции независимы друг от друга – если они могут выполняться в любом порядке, не обращаются к одним и тем же переменным и не изменяют их.
Синхронизация и директива critical
Директива critical исключает параллельное выполнение следующего за ней оператора.
{$omp critical имя}
оператор;
Этот оператор образует критическую секцию – участок кода, который не может выполняться одновременно несколькими потоками.
Только критические секции с одинаковыми именами не могут выполняться одновременно. Если один поток уже выполняет критическую секцию, а второй пытается войти в секцию с таким же именем, он будет заблокирован до тех пор, пока первый поток не выйдет за пределы критической секции.
Критические секции можно использовать при обращении к общим переменным, чтобы избежать потерь данных.
var a:integer:=0;
{$omp parallel for}
for var i:integer:=1 to 100 do
{$omp critical}
a:=a+1;
Здесь критическую секцию можно использовать вместо редукции. Весь оператор a:=a+1 выполнится одним потоком и только потом – другим. Однако использование критических секций обычно снижает эффективность за счет последовательного выполнения этих участков. В этом примере все тело цикла является критической секцией, поэтому весь цикл будет выполнен последовательно.
Но не во всех случаях использование критических секций помогает обеспечить корректную работу параллельных конструкций.
var a:integer := 0;
{$omp parallel sections}
begin
{$omp critical}
a:=1;
{$omp critical}
a:=a+1;
end;
Значение переменной a зависит от того, в каком порядке выполнятся секции. Если первая секция выполнится раньше, значение a будет равно двум, иначе – единице.
При использовании критических секций возможно возникновение взаимоблокировок. Например, первый поток выполняет код, содержащий критическую секцию A, внутри которой есть критическая секция B. Второй поток выполняет код, содержащий критическую секцию B, внутри которой есть критическая секция A. Возможен такой порядок выполнения: первый поток входит в секцию А и не успевает войти в секцию В. Второй поток входит в секцию В и не может войти в секцию А, так как эта секция уже выполняется другим потоком. Первый поток не может продолжить выполнение, так как секция В уже выполняется другим потоком. Оба потока оказываются заблокированными.
Стандартные модули
Модуль GraphABC
Модуль GraphABC представляет собой простую графическую библиотеку и предназначен для создания несобытийных графических и анимационных программ в процедурном и частично в объектном стиле. Рисование осуществляется в специальном графическом окне, возможность рисования в нескольких окнах отсутствует. Кроме этого, в модуле GraphABC определены простейшие события мыши и клавиатуры, позволяющие создавать элементарные событийные приложения. Основная сфера использования модуля GraphABC - обучение.
Модуль GraphABC основан на графической библиотеке GDI+, но запоминает текущие перо, кисть и шрифт, что позволяет не передавать их в качестве параметров при вызове графических примитивов. К свойствам пера, кисти и шрифта можно получать доступ как в процедурном, так и в объектном стиле. Например, для доступа к цвету текущего пера используется процедура SetPenColor(c) и функция PenColor, а также свойство Pen.Color.
В модуле GraphABC можно управлять самим графическим окном и компонентом GraphABCControl, на котором осуществляется рисование. По умолчанию компонент GraphABCControl занимает всю клиентскую часть графического окна, однако, на графическое окно можно добавить элементы управления, уменьшив область, занимаемую графическим компонентом (например, так сделано в модулях Robot и Drawman).
Для работы с рисунками используется класс Picture, позволяющий рисовать на себе те же графические примитивы, что и на экране.
Режим блокировки рисования на экране (LockDrawing) позволяет осуществлять прорисовку лишь во внеэкранном буфере, после чего с помощью метода Redraw восстанавливать все графическое окно. Данный метод используется для ускорения анимации и создания анимации без мерцания.
В модуле GraphABC определен ряд констант, типов, процедур, функций и классов для рисования в графическом окне. Они подразделяются на следующие группы:
Графические примитивы
Функции для работы с цветом
Цветовые константы
Действия с пером: процедуры и функции
Действия с пером: объект Pen
Стиль пера
Действия с кистью: процедуры и функции
Действия с кистью: объект Brush
Стили кисти
Стили штриховки кисти
Действия со шрифтом: процедуры и функции
Действия со шрифтом: объект Font
Стили шрифта
Действия с рисунками: класс Picture
Действия с графическим окном: процедуры и функции
Действия с графическим окном: объект Window
Действия с системой координат: процедуры и функции
Действия с системой координат: объект Coordinate
Блокировка рисования и ускорение анимации
Режимы рисования
События GraphABC
Виртуальные коды клавиш
Перенаправление ввода-вывода
Типы и переменные модуля GraphABC
Color = System.Drawing.Color;
Тип цвета
Point = System.Drawing.Point;
Тип точки
GraphABCException = class(Exception) end;
Тип исключения GraphABC
RedrawProc: procedure;
Процедурная переменная перерисовки графического окна. Если равна nil, то используется стандартная перерисовка
DrawInBuffer: boolean;
Следует ли рисовать во внеэкранном буфере
Графические примитивы
Графические примитивы представляют собой процедуры, осуществляющие рисование в графическом окне. Рисование осуществляется текущим пером (линии), текущей кистью (заливка замкнутых областей) и текущим шрифтом (вывод строк).
procedure SetPixel(x,y: integer; c: Color);
Закрашивает пиксел с координатами (x,y) цветом c
procedure PutPixel(x,y: integer; c: Color);
Закрашивает пиксел с координатами (x,y) цветом c
function GetPixel(x,y: integer): Color;
Возвращает цвет пиксела с координатами (x,y)
procedure MoveTo(x,y: integer);
Устанавливает текущую позицию рисования в точку (x,y)
procedure LineTo(x,y: integer);
Рисует отрезок от текущей позиции до точки (x,y). Текущая позиция переносится в точку (x,y)
procedure LineTo(x,y: integer; c: Color);
Рисует отрезок от текущей позиции до точки (x,y) цветом c. Текущая позиция переносится в точку (x,y)
procedure Line(x1,y1,x2,y2: integer);
Рисует отрезок от точки (x1,y1) до точки (x2,y2)
procedure Line(x1,y1,x2,y2: integer; c: Color);
Рисует отрезок от точки (x1,y1) до точки (x2,y2) цветом c
procedure FillCircle(x,y,r: integer);
Заполняет внутренность окружности с центром (x,y) и радиусом r
procedure DrawCircle(x,y,r: integer);
Рисует окружность с центром (x,y) и радиусом r
procedure FillEllipse(x1,y1,x2,y2: integer);
Заполняет внутренность эллипса, ограниченного прямоугольником, заданным координатами противоположных вершин (x1,y1) и (x2,y2)
procedure DrawEllipse(x1,y1,x2,y2: integer);
Рисует границу эллипса, ограниченного прямоугольником, заданным координатами противоположных вершин (x1,y1) и (x2,y2)
procedure FillRectangle(x1,y1,x2,y2: integer);
Заполняет внутренность прямоугольника, заданного координатами противоположных вершин (x1,y1) и (x2,y2)
procedure FillRect(x1,y1,x2,y2: integer);
Заполняет внутренность прямоугольника, заданного координатами противоположных вершин (x1,y1) и (x2,y2)
procedure DrawRectangle(x1,y1,x2,y2: integer);
Рисует границу прямоугольника, заданного координатами противоположных вершин (x1,y1) и (x2,y2)