Воскресенье, 05.05.2024, 07:48
Приветствую Вас Guest Member

Windows XP / 7 .

[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 3
  • 1
  • 2
  • 3
  • »
Архив - только для чтения
Форум <<Помощь по компьютерам>> » Низкоуровневое программирование » Исходные коды » Исходные коды: Delphi (Исходные коды: Delphi)
Исходные коды: Delphi
MafiozikOДата: Суббота, 22.08.2009, 23:15 | Сообщение # 1
~Web master~
Группа: Gold пользователь
Зарегистрирован: 10.04.2009
Откуда: Kharkiv
Пол: Мужчина
Сообщений: 366
Статус: Вне сайта
Библиотеки
Gala

Библиотека параллельного программирования для Delphi. Реализация библиотеки Gala опирается на низкоуровневые возможности параллельного программирования, предоставляемые платформой Win32 (Windows 95, 98, NT, 2000): потоки, сигналы, мьютексы, семафоры, критические секции, сообщения. Gala позволяет решать различные программистские задачи на основе асинхронных взаимодействующих параллельных процессов и разделяемых ресурсов, существующих в рамках одной Windows-программы.
GsvThread

Еще одна библиотека параллельного программирования для Delphi. Представляет собой облегченную версию библиотеки Gala.
DccUsing

Использование компилятора Delphi (dcc32.exe) в прикладных программах. Библиотека демонстрирует поддержку технологии многозвенного программирования применительно к Delphi.


Админ
 
MafiozikOДата: Суббота, 22.08.2009, 23:16 | Сообщение # 2
~Web master~
Группа: Gold пользователь
Зарегистрирован: 10.04.2009
Откуда: Kharkiv
Пол: Мужчина
Сообщений: 366
Статус: Вне сайта
Gala

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

Так получилось, что большая часть программистских задач, которые мне приходилось решать, наиболее адекватно декомпозировались именно в терминах параллельных процессов и их взаимодействий - именно этим определяется мой интерес к этой теме. Существуют языки, которые непосредственно поддерживают конструкции параллельного программирования, например, Ада и Оккам, но первый - чересчур громоздкий и сложный, для него нет доступного и качественного компилятора, работающего в среде Windows, а второй - Оккам - достаточно специфичный язык, разработанный специально для программирования транспьютеров фирмы Inmos [2]. В тоже время есть доступные и качественные Windows-инструменты: объектно-ориентированные языки последовательного программирования C++ и Delphi, которые можно естественно расширить для реализации концепций параллельного программирования, используя понятие класса. В статье описывается библиотека классов Gala для Delphi. Если мне придется программировать в среде C++ Builder или Visual C++, то я перепишу Gala на C++. Подобная библиотека (2kLib) была ранее сделана мной для DOS и Borland C++ [1].

Реализация библиотеки Gala опирается на низкоуровневые возможности параллельного программирования, предоставляемые платформой Win32 (операционные системы Windows 95, 98, NT, 2000) - потоки, сигналы, мьютексы, семафоры, критические секции, сообщения. Библиотека позволяет выполнять декомпозицию задачи с использованием асинхронных взаимодействующих параллельных процессов и разделяемых ресурсов, существующих в рамках одной Windows-программы. Delphi предоставляет класс TThread, но его функциональность ограничивается, в основном, взаимодействием с VCL-компонентами, которые не являются потокобезопасными. TThread не дает никаких методов взаимодействия с другими параллельными процессами (потоками). Этот класс удобно использовать, когда в программе малое количество статически создаваемых процессов (потоков), взаимодействующих с основным VCL-потоком и не взаимодействующих между собой. Если же задача раскладывается на достаточно большое число динамически создаваемых, уничтожаемых и взаимодействующих между собой процессов, то использование TThread становится очень сложным и ненадежным. Непосредственное же использование разнообразных низкоуровневых средств синхронизации Win32 чрезвычайно трудоемко, чревато ошибками и громоздко (хотя и более эффективно).
Сказка

В некотором царстве, в некотором государстве жил-был Бармалеус. И был у него театр. Рано утречком Бармалеус открывал театр и убирался в нем, готовил сцену и ждал вечера, когда начнется спектакль. К вечеру собирались актеры и режиссер. А надо сказать, что режиссер был весьма необыкновенным - он каждый день придумывал новый спектакль, и актеры каждый день играли новые роли без всяких репетиций. Режиссер был очень авторитарным человеком - он требовал от актеров точного исполнения действий, которые он видел в своем воображении, но поскольку он, кроме этого, был культурным и вежливым человеком, то свои требования он выражал сообщениями-записками, которые посылал каждому актеру. А начинались сообщения со слов - "Будьте так добры, сделайте, пожалуйста, то-то и то-то". Все актеры были профессионалами и легко понимали режиссера. И были актеры такими же вежливыми и культурными, они экономили процессорное время и не строили козни другим актерам. А если им для выполнения своих действий что-то было нужно, то они направляли такие же вежливые сообщения-записочки рабочим сцены. И никто не ругался ненормативной лексикой и не пил за кулисами водку.



Админ
 
MafiozikOДата: Суббота, 22.08.2009, 23:17 | Сообщение # 3
~Web master~
Группа: Gold пользователь
Зарегистрирован: 10.04.2009
Откуда: Kharkiv
Пол: Мужчина
Сообщений: 366
Статус: Вне сайта
Действующие лица и исполнители

ГалаТеатр
Это то место, где происходит рождение, жизнь и смерть ГалаПроцессов. В программе может быть только один объект GalaTheater (так же как объект Application). ГалаТеатр позволяет объединять процессы в группы-кластеры. Как правило, процессы взаимодействуют только внутри группы. В программе может быть одна или несколько групп. Можно провести такую аналогию - группа это сцена. В театре может быть несколько сцен, на каждой из которых разыгрывается свой собственный спектакль. ГалаТеатр предоставляет методы для создания и завершения группы процессов, отладочной трассировки и протоколирования работы процессов.
ГалаПроцесс
Это основное действующее лицо в ГалаТеатре. Все процессы в ГалаТеатре порождаются от базового класса TGalaProcess, который имеет виртуальный абстрактный метод Execute - именно в нем описывается алгоритм функционирования процесса. Базовый ГалаПроцесс инкапсулирует поток (thread) Win32 без использования Delphi-класса TThread и имеет методы для:

* завершения процесса, реализации действий при нормальном и принудительном завершении;
* получения и изменения его приоритета;
* приостановки, запуска и приостановки на заданный промежуток времени;
* взаимодействия с основным VCL-потоком, с другими параллельными процессами и разделяемыми ресурсами;
* отладочной трассировки.


Админ
 
MafiozikOДата: Суббота, 22.08.2009, 23:17 | Сообщение # 4
~Web master~
Группа: Gold пользователь
Зарегистрирован: 10.04.2009
Откуда: Kharkiv
Пол: Мужчина
Сообщений: 366
Статус: Вне сайта
Объект ГалаПроцесса явно создается конструктором, но не уничтожается явно при завершении процесса, а только освобождает основные системные ресурсы. Уничтожение объектов ГалаПроцессов выполняется ГалаТеатром и только для всей группы взаимодействующих процессов - это позволяет корректно обрабатывать ситуации взаимодействия с уже завершенным процессом. Операция принудительного завершения заканчивает процесс даже в том случае, если он приостановлен или ожидает какого-либо события. Принудительное завершение процесса выглядит как директива-предписание, но завершающие действия выполняются процессом самостоятельно. ГалаПроцесс может владеть каналами для взаимодействия с другими ГалаПроцессами и посылать сообщения основному VCL-потоку. Для взаимодействия с другими параллельными процессами и разделяемыми ресурсами используется модель асимметричного рандеву - как в языке Ада. По сравнению с симметричным рандеву, принятым в языке Оккам, асимметричное рандеву имеет три важных преимущества. Во-первых, это позволяет явно разделить процессы на два больших класса - клиенты и серверы, во-вторых, позволяет делать независимую (библиотечную) реализацию серверов, так как при асимметричном рандеву серверам не требуется знание своих клиентов и, в-третьих, унифицировать взаимодействия Процесс-Процесс и Процесс-РазделяемыйРесурс. Для выполнения недетерминированного ожидания по своим каналам ГалаПроцесс имеет метод AlternativeAccept, который подобен оператору отбора select / or языка Ада [7], или оператору Alt языка Оккам [2]. Метод AlternativeAccept ожидает первого поступившего запроса по заданным каналам или возбуждает исключительную ситуацию EGalaTimeout, если взаимодействие не произошло за указанное время.
ГалаКонтейнер
Пассивный ресурс, разделяемый несколькими ГалаПроцессами. Объекты этого класса порождаются от базового класса TGalaContainer. ГалаКонтейнер может владеть каналами, посредством которых ГалаПроцессы получают доступ к разделяемому ресурсу. Сам контейнер ничего не делает, он только владеет каналами, которые все и делают. Каналы ГалаКонтейнера позволяют выполнять доступ к совместно используемым данным одновременно многим процессам в режиме взаимного исключения. Если контейнер не может в данный момент времени удовлетворить запрос, то он приостанавливает вызывающий процесс, а после завершения очередной операции в контейнере активизирует все ожидающие процессы так, чтобы они опять вступили в конкуренцию за обладание ресурсами контейнера. ГалаКонтейнеры подобны процессам-серверам, но более эффективны и потребляют меньше системных ресурсов, чем ГалаПроцессы. Контейнеры можно использовать вместо процессов в тех случаях, когда назначение контейнера только в том, чтобы предоставить доступ нескольким процессам к одному ресурсу. В отличие от процессов, контейнеры создаются, как правило, не динамически, а статически.
ГалаСообщение
Позволяет взаимодействовать ГалаПроцессу с основным VCL-потоком с помощью посылки окну (форме) синхронного Windows-сообщения методом Send. Для ответа на такое сообщение в VCL-форме определяется соответствующий метод. Данные передаются в сообщении с помощью бестипового указателя, что позволяет выполнить двунаправленный обмен данными любого типа. На время обработки сообщения, вызвавший процесс приостанавливается.
ГалаКанал
Позволяет ГалаПроцессам взаимодействовать друг с другом и с ГалаКонтейнерами. ГалаКаналами владеют либо ГалаПроцессы, либо ГалаКонтейнеры. Каждый канал может получать сообщения одновременно от нескольких процессов. Объект-ГалаКанал может быть типа TGalaProcessChannel или TGalaContainerChannel в зависимости от того, кто будет создавать и владеть этим каналом. Создаются объекты каналов явно в конструкторах ГалаПроцесса или ГалаКонтейнера с помощью функции CreateChannel, а уничтожаются автоматически при уничтожении владельцев. Действия над данными, реализуемые при передаче сообщения в канал, описываются во входной (серверной) процедуре - она вызывается каналом в режиме взаимоисключения. Охраняющая функция определяет условие, при котором входная процедура может быть вызвана. Входная процедура соответствует входу entry оператора accept, а охраняющая функция - оператору when (язык Ада [7]). Для взаимодействия с ГалаПроцессами в канале определен метод Send, принимающий указатели на посылающий процесс и на посылаемые-принимаемые данные. Использование бестипового указателя позволяет передавать по каналу данные любого типа в обоих направлениях.
ГалаСигнал


Админ
 
MafiozikOДата: Суббота, 22.08.2009, 23:17 | Сообщение # 5
~Web master~
Группа: Gold пользователь
Зарегистрирован: 10.04.2009
Откуда: Kharkiv
Пол: Мужчина
Сообщений: 366
Статус: Вне сайта
Кроме взаимодействий с другими процессами, ГалаПроцессы могут ожидать сигналы. Сигналы несут в себе только факт наступления некоторых событий, как связанных с другими процессами, так и с внешними событиями, происходящими в операционной системе. ГалаСигналы представляются собой набор таких средств, инкапсулирующих примитивы, непосредственно предоставляемые операционной системой - события, мьютексы, семафоры и файловые уведомления. Использование их необязательно, но иногда более удобно, особенно в тех случаях, когда не требуется обмен данными, а важен сам факт наступления некоторого события. Все ГалаСигналы порождаются от базового класса TGalaSignal и имеют метод Wait. Метод Wait позволяет ограничить время ожидания и отслеживает факт получения ожидающим процессом директивы завершения, что дает возможность выполнить корректное принудительное завершение процесса, находящегося в состоянии ожидания.

Админ
 
MafiozikOДата: Суббота, 22.08.2009, 23:18 | Сообщение # 6
~Web master~
Группа: Gold пользователь
Зарегистрирован: 10.04.2009
Откуда: Kharkiv
Пол: Мужчина
Сообщений: 366
Статус: Вне сайта
Действующие лица и исполнители. Продолжение

ГалаТеатр

Code
TGalaTheater = class
public
   constructor Create;
   destructor  Destroy; override;

   function  GetNewGroup: Integer;
   procedure ResumeGroup(aGroup: Integer);
   procedure SuspendGroup(aGroup: Integer);
   function  TerminateAllProcesses: Boolean;
   function  TerminateGroup(aGroup: Integer): Boolean;
   function  TryToDestroyAllProcesses: Boolean;
   function  TryToDestroyGroup(aGroup: Integer): Boolean;
   procedure DestroyAllProcesses;
   procedure DestroyGroup (aGroup: Integer);
   property  Log(const S: string);

   property  PriorityClass: Integer read GalaGetPriorityClass
             write GalaSetPriorityClass;
   property  NotificationWindow: HWND read FNotificationWindow
             write FNotificationWindow;
end;

var
   GalaTheater: TGalaTheater;


Админ
 
MafiozikOДата: Суббота, 22.08.2009, 23:18 | Сообщение # 7
~Web master~
Группа: Gold пользователь
Зарегистрирован: 10.04.2009
Откуда: Kharkiv
Пол: Мужчина
Сообщений: 366
Статус: Вне сайта
Объект GalaTheater создается конструктором Create и уничтожается деструктором Destroy. Аналогично объекту Application в программе может быть только один объект GalaTheater. Удобное место для создания и уничтожения ГалаТеатра - методы FormCreate и FormDestroy (или FormClose) главной формы приложения. Процессы в ГалаТеатре существуют группами. Группа характеризует связанность процессов, - процессы взаимодействуют между собой только внутри группы. Исключение составляют серверные (системные) процессы, которые объединяются в одну группу и предоставляют сервисы процессам остальных групп. Функция GetNewGroup позволяет получить уникальный номер группы в том случае, если в вашей программе будет несколько групп, создающихся и уничтожающихся динамически. Если в программе одна или несколько статических групп, то идентификаторы (номера) групп можно задать константами (начиная от 1). Перед закрытием ГалаТеатра нужно завершить все (еще работающие) процессы. Закрыть ГалаТеатр можно только из VCL-потока: функция TerminateAllProcesses вызывает функцию завершения (Terminate) для всех еще активных процессов (ах, эти актеры - им только дай поиграть! - прямо как дети малые). Функция TryToDestroyAllProcesses сначала вызывает TerminateAllProcesses и только если все процессы уже завершены, уничтожает их. Если в процессе уничтожения обнаруживается новый процесс, то ему посылается уведомление о завершении, уничтожение процессов прекращается и функция возвращает False. Такое явление может случиться в том случае, если ГалаПроцесс создал новый процесс и только после этого получил уведомление о завершении. Функция возвращает True, если все процессы ГалаТеатра успешно уничтожены. Аналогично работают функции TerminateGroup и TryToDestroyGroup, но в отличие от предыдущих функций они закрывают и уничтожают только процессы указанной группы и могут быть вызваны не только из VCL-потока, но и из процесса другой группы. Процедура SuspendGroup позволяет одновременно приостановить, а ResumeGroup - активизировать все процессы группы. Процедуры DestroyAllProcesses и DestroyGroup уничтожают все процессы ГалаТеатра или процессы заданной группы и дожидаются полного завершения операции уничтожения. Свойство PriorityClass позволяет изменить класс приоритета всех процессов ГалаТеатра. Свойство NotificationWindow задает окно, в которое будут посылаться уведомления о создании, уничтожении и трассировке процесса. Эта информация полезна при отладке. Если окно не задано, то уведомляющие сообщения не посылаются. Свойство Log выводит отладочную строку в файл протокола (обеспечивая взаимное исключение процессов).

Админ
 
MafiozikOДата: Суббота, 22.08.2009, 23:19 | Сообщение # 8
~Web master~
Группа: Gold пользователь
Зарегистрирован: 10.04.2009
Откуда: Kharkiv
Пол: Мужчина
Сообщений: 366
Статус: Вне сайта
ГалаПроцесс

Code
TGalaProcess = class
protected
   FSuspendedOnStart: Boolean;
   FStackSize:        Integer;

   function  CreateChannel(aEntry: TGalaEntry;
             aGuard: TGalaGuard = nil): TGalaProcessChannel;
   procedure Execute; virtual; abstract;
   procedure OnNormalTermination; virtual;
   procedure OnPrematureTermination; virtual;
   procedure OnUnhandledException(E: Exception); virtual;

   procedure Trace(const S: string);
   procedure Log(const S: string);
   procedure Pause(aTime: Cardinal);
   procedure Send(aMessageId: Cardinal; aData: Pointer = nil;
             aForm: TForm = nil;  aTimeout: Cardinal = INFINITE);
   procedure Accept(aChannel: TGalaProcessChannel;
             aTimeout: Cardinal = INFINITE);
   procedure AlternativeAccept(aChannels: array of TGalaProcessChannel;
             aTimeout: Cardinal = INFINITE);
   procedure Wait(aSignal: TGalaSignal;
             aTimeout: Cardinal = INFINITE);
   function  AlternativeWait(aSignals: array of TGalaSignal;
             aTimeout: Cardinal = INFINITE): Integer;
   procedure WaitCompletion(const aProcesses: array of TGalaProcess;
             aTimeout: Cardinal = INFINITE);

public
   ProcessName:     string;
   FreeOnTerminate: Boolean;

   constructor Create(aGroup: Integer; aParentForm: TForm = nil);
   destructor  Destroy; override;

   procedure Terminate;
   procedure Suspend;
   procedure Resume;

   property Handle: THandle read FHandle;
   property Suspended: Boolean read FSuspended;
   property Terminated: Boolean read FTerminated;
   property Finished: Boolean read FFinished;
   property Priority: Integer read GetPriority write SetPriority;
end;


Админ
 
MafiozikOДата: Суббота, 22.08.2009, 23:20 | Сообщение # 9
~Web master~
Группа: Gold пользователь
Зарегистрирован: 10.04.2009
Откуда: Kharkiv
Пол: Мужчина
Сообщений: 366
Статус: Вне сайта
ГалаПроцесс создается явным вызовом его конструктора Create, которому передается номер группы и ссылка на форму, с которой процесс будет наиболее плотно взаимодействовать. Как правило, это форма, из которой вызван конструктор процесса. Если в программе только одна группа процессов, то номер группы можно задавать константой 1. Ошибка при создании процесса будет возбуждать исключительную ситуацию EGalaObjectCreationFail. Собственно тело процесса программируется в методе Execute, который обязательно должен быть переопределен в наследуемом классе. Если процесс завершается нормально, то он освобождает основные системные ресурсы, но объект процесса продолжает существовать и уничтожается только ГалаТеатром - и только вместе со своей группой. Попытка взаимодействия с завершенным процессом будет возбуждать исключение EGalaProcessWasTerminated. Для принудительного завершения процесса нужно вызвать процедуру Terminate. Действие ее состоит в следующем: она устанавливает флажок Terminated и активизирует внутренний сигнал процесса FTerminationEvent, который выводит процесс из состояния ожидания (если процесс в нем находится). В ходе выполнения метода Execute процесс должен периодически контролировать свойство Terminated и выполнять завершающие действия, например:

Code
while not Terminated do begin
   // действия процесса
end;
// завершающие действия

Принудительное завершение - это очень важное событие и оно учитывается всеми остальными объектами ГалаТеатра. Синхронизация процессов всегда связана с ожиданием, при котором процесс переходит в спящее состояние - ожидание некоторого события. И если это событие уже не произойдет (например, завершился другой процесс, генерирующий это событие), то ожидающий процесс никогда не проснется, что приведет к зависанию программы. Поэтому уход процесса в спящее ожидание всегда охраняется таймаутом (необязательным) и реакцией на принудительное завершение (обязательной). Если в то время, когда процесс находится в спящем состоянии, он получает директиву принудительного завершения, то процесс активизируется и в нем возбуждается исключительная ситуация EGalaPrematureTermination. Если процесс явно ее не перехватывает, то нормальная работа процесса завершается и вызывается виртуальное событие OnPrematureTermination, которое может быть переписано в наследуемом классе. При нормальном завершении вызывается виртуальное событие OnNormalTermination. Конечно, процесс может выполнить нормальные завершающие действия и в методе Execute, но выделение их в отдельное событие более логично. Обычно принудительное завершение ГалаПроцесса находится в компетенции ГалаТеатра (и VCL-потока), но этим правом могут воспользоваться также ГалаПроцессы, если у них есть на это веские основания (приходится мириться с демократией в разумных пределах).


Админ
 
MafiozikOДата: Суббота, 22.08.2009, 23:20 | Сообщение # 10
~Web master~
Группа: Gold пользователь
Зарегистрирован: 10.04.2009
Откуда: Kharkiv
Пол: Мужчина
Сообщений: 366
Статус: Вне сайта
При возникновении необработанной явным образом исключительной ситуации, управление передается обработчику события OnUnhandledException, который выводит информационное сообщение и завершает выполнение ГалаПроцесса. Вы его можете переписать в наследуемом классе для реализации собственной индивидуальной реакции на необработанные исключения.

В конструкторе процесса можно задать:

* его имя (ProcessName), которое используется при отладочных уведомлениях (по умолчанию - это имя класса);
* максимальный размер стека процесса FStackSize (по умолчанию - 1 мб). При создании процесса ему выделяется начальный стек в 8 кб, который растет динамически по мере необходимости;
* признак приостановки при создании процесса FSuspendedOnStart. По умолчанию процесс после создания сразу же активизируется. Часто это умолчание недопустимо, так как процесс сразу же может начать взаимодействовать с еще не созданными процессами. Для того, чтобы корректно обработать эту ситуацию, все взаимодействующие процессы запускаются в 2 этапа: сначала создаются как неактивные (подвешенные), а потом уже активизируются. Для активизации приостановленного процесса используется процедура Resume. Для активизации всех процессов группы можно использовать метод ГалаТеатра ResumeGroup;
* признак самоуничтожения при завершении FFreeOnTerminate - использовать его нужно очень осторожно и устанавливать только в том случае, если процесс не взаимодействует ни с каким другим Гала-процессом. Этот признак - лазейка в общей стратегии уничтожения процессов;
* стартовый приоритет процесса Priority.


Админ
 
MafiozikOДата: Суббота, 22.08.2009, 23:20 | Сообщение # 11
~Web master~
Группа: Gold пользователь
Зарегистрирован: 10.04.2009
Откуда: Kharkiv
Пол: Мужчина
Сообщений: 366
Статус: Вне сайта
По ходу работы сам процесс может менять свой приоритет, а также процессы могут менять приоритеты друг друга. Значения приоритетов следующие:

Code
-3 // низший приоритет (Idle)
-2 // на 2 пункта ниже нормального
-1 // на 1 пункт ниже нормального
  0 // нормальный приоритет
  1 // на 1 пункт выше нормального
  2 // на 2 пункта выше нормального
  3 // высший приоритет (Time Critical)

Процесс может приостанавливать свою работу на заданный промежуток времени вызовом метода Pause, которому передается значение времени в миллисекундах. Если во время паузы процессу будет передана директива принудительного завершения, то пауза будет прервана и возбуждена исключительная ситуация EGalaPrematureTermination.

Для взаимодействия с основным VCL-потоком ГалаПроцесс посылает VCL-форме сообщение с помощью метода Send. Этот метод имеет аргументы:

* идентификатор сообщения (целое число);
* бестиповый указатель на передаваемые-принимаемые данные (Pointer). По умолчанию данные - это ссылка на сам процесс;
* ссылка на форму, которой направляется сообщение. По умолчанию - это ParentForm;
* время таймаута в миллисекундах (по умолчанию - бесконечность).


Админ
 
MafiozikOДата: Суббота, 22.08.2009, 23:21 | Сообщение # 12
~Web master~
Группа: Gold пользователь
Зарегистрирован: 10.04.2009
Откуда: Kharkiv
Пол: Мужчина
Сообщений: 366
Статус: Вне сайта
Такой способ взаимодействия с VCL-потоком обусловлен тем, что VCL-компоненты не являются потокобезопасными, то есть попытка одновременного обращения к VCL-компоненту из двух и более потоков приведет к разрушению данных компонента и, как правило, к аварийному прекращению программы. Поэтому необходим взаимоисключающий доступ к VCL-компонентам. Операционная система Windows позволяет сделать такой доступ с помощью функций SendMessage и SendMessageTimeout. Метод Send инкапсулирует вызовы этих функций и упаковку данных в стандартное сообщение Windows. Рандеву с VCL-потоком заключается в посылке окну формы заданного синхронного сообщения. При этом потоки синхронизируются - то есть, если VCL-поток не готов обслужить данный поток (поток посылающего ГалаПроцесса), то он ставится в очередь и выполнение потока будет приостановлено. Если VCL-поток готов, то он выполняет взаимодействие, после чего оба потока будут продолжаться параллельно. В процессе рандеву VCL-поток принимает Windows-сообщение, в поле LParam которого находится указатель на объект данных, получает данные и при необходимости изменяет их, возвращая, таким образом, результат рандеву. Для реализации второй стыковочной части рандеву, форма должна иметь метод такого вида:

Code
procedure OnXXX(var Mes: TMessage); message GM_ON_XXX;

где Mes - это структура, в поле LParam которой записана ссылка на посланные данные. В ходе своего выполнения метод может получить указатель на конкретный тип с помощью, например, такой операции:

Code
with TAnyData(Mes.LParam) do begin
   // действия с данными
end;

где TAnyData - любой тип данных. В качестве данных может выступать ссылка на сам посылающий процесс. В качестве идентификатора сообщения можно использовать константы со значением GM_USER и больше (префикс GM означает - Gala Message). Метод может принимать необязательный аргумент - время ожидания в миллисекундах. Если за указанное время взаимодействие не произошло, то возбуждается исключительная ситуация EGalaTimeout. Этот параметр можно использовать для предотвращения зависания программы при интенсивном взаимодействии ГалаПроцессов с VCL-потоком, при котором формы настолько заняты, что просто перестают реагировать на мышь и клавиатуру.


Админ
 
MafiozikOДата: Суббота, 22.08.2009, 23:21 | Сообщение # 13
~Web master~
Группа: Gold пользователь
Зарегистрирован: 10.04.2009
Откуда: Kharkiv
Пол: Мужчина
Сообщений: 366
Статус: Вне сайта
ГалаПроцесс может ожидать рандеву с другими ГалаПроцессами по каналам, которыми он владеет. Для реализации рандеву по одному каналу ГалаПроцесс вызывает метод Accept, для недетерминированного ожидания по нескольким своим каналам - метод AlternativeAccept, который ожидает рандеву по любому из заданных каналов. Более подробное описание взаимодействия будет дано ниже, при рассмотрении ГалаКаналов. Время ожидания по обоим методам может быть ограничено указанием таймаута. Приведем пример соответствия конструкций ГалаТеатра и языка Ада. Текст на Аде:

Code
entry Entry1;
entry Entry2;
function CanEntry2 return BOOLEAN;
. . .
   select
     accept Entry1;
   or
     when CanEntry2 =>
       accept Entry2;
   or
     delay 0.1;
   end select;
. . .


Админ
 
MafiozikOДата: Суббота, 22.08.2009, 23:22 | Сообщение # 14
~Web master~
Группа: Gold пользователь
Зарегистрирован: 10.04.2009
Откуда: Kharkiv
Пол: Мужчина
Сообщений: 366
Статус: Вне сайта
В этом примере программа ожидает недетерминированного взаимодействия по входам Entry1 и Entry2 с ограничением по времени в 0.1 секунду. Вход Entry2 ожидается только в том случае, если функция CanEntry2 возвращает TRUE. Соответствующий код для Gala-библиотеки:

Code
Entry1, Entry2: TGalaProcessChannel;
procedure DoEntry1(aData: Pointer);
procedure DoEntry2(aData: Pointer);
function  CanEntry2: Boolean;
. . .  
Entry1 := CreateChannel(DoEntry1);
Entry2 := CreateChannel(DoEntry2, CanEntry2);
. . .
AlternativeAccept([Entry1, Entry2], 100);

В отличие от языка Ада, где входы реализуются как процедуры, входы в Gala-библиотеке реализуются как каналы, содержащие соответствующие процедуры и охраняющие функции. В данном случае канал1 вызывает процедуру-обработчик DoEntry1, а канал2 - DoEntry2 и CanEntry2.

Кроме ожидания рандеву по каналам, ГалаПроцессы могут ожидать сигналы. Для ожидания одиночного сигнала ГалаПроцесс вызывает метод Wait. Для альтернативного недетерминированного ожидания нескольких событий (сигналов) ГалаПроцесс вызывает метод AlternativeWait, которому передается массив объектов-сигналов. Время ожидания по обоим методам может быть ограничено заданием таймаута. Объединить альтернативное ожидание и рандеву и сигналов в одном действии невозможно, так они имеют фундаментальные отличия: при рандеву происходит обмен данными, при ожидании - нет, рандеву предполает двух активных партнеров (ГалаПроцессов), а ожидание - только одного. Для реализации такого объединения можно использовать следующий прием: создается промежуточный процесс, ожидающий только сигналы и преобразующий их в сообщения, передаваемые по каналам процессу, выполняющему недетерминированное ожидание.


Админ
 
MafiozikOДата: Суббота, 22.08.2009, 23:22 | Сообщение # 15
~Web master~
Группа: Gold пользователь
Зарегистрирован: 10.04.2009
Откуда: Kharkiv
Пол: Мужчина
Сообщений: 366
Статус: Вне сайта
ГалаКаналы

ГалаКаналы - это исполнители, реализующие взаимодействия между процессами. Каналы ГалаПроцессов и ГалаКонтейнеров внешне полностью совпадают, но имеют различную реализацию:

Code

TGalaContainerChannel = class
public
   procedure Send(aSender: TGalaProcess; aData: Pointer = nil;
                 aTimeout: Cardinal = INFINITE);
   property Entry: TGalaEntry read FEntry write FEntry;
   property Guard: TGalaGuard read FGuard write FGuard;
end;

TGalaProcessChannel = class
public
   procedure Send(aSender: TGalaProcess; aData: Pointer = nil;
                 aTimeout: Cardinal = INFINITE);
   property Entry: TGalaEntry read FEntry write FEntry;
   property Guard: TGalaGuard read FGuard write FGuard;
end;

Создаются каналы с помощью вызова метода CreateChannel в конструкторах ГалаКонтейнера и ГалаКанала, а уничтожаются автоматически в их деструкторах. Метод CreateChannel у ГалаПроцесса точно такой же, как и у ГалаКонтейнера и имеет аргументы:

* ссылку на процедуру-обработчик (Entry), которая выполняет функциональную обработку данных (aData), передаваемых в процессе рандеву. Обработчик должен быть методом ГалаПроцесса или ГалаКонтейнера и иметь такой тип: TGalaEntry = procedure(aData: Pointer) of object;
* необязательную ссылку на охраняющую функцию (Guard), которая выполняет роль предохранителя, разрешающего или запрещающего вызов обработчика Entry - факт того, что рандеву может состояться.


Админ
 
Форум <<Помощь по компьютерам>> » Низкоуровневое программирование » Исходные коды » Исходные коды: Delphi (Исходные коды: Delphi)
  • Страница 1 из 3
  • 1
  • 2
  • 3
  • »
Поиск: