К возможным вариантам относятся четыре объекта, которые разработаны специально для синхронизации: событие (event), взаимное исключение (mutex), семафор (semaphore) и таймер (timer).

24 Зак. 55')

Но кроме специальных объектов можно организовать ожидание и других объектов, дескриптор которых используется в основном для иных целей, но может применяться и для ожидания. К ним относятся: процесс (process), поток (thread), оповещение об изменении в файловой системе (change notification) и консольный ввод (console input).

Косвенно к этой группе может быть добавлена критическая секция (critical section).

Перечисленные выше средства синхронизации в основном инкапсулированы в состав классов Delphi. У программиста есть две альтернативы. С одной стороны, в состав библиотеки VCL включен модуль SYNCOBJS.PAS, содержащий классы для события (TEvent) и критической секции (TCriticalSection). С другой, с Delphi поставляется отличный пример IPCDEMOS, который иллюстрирует проблемы взаимодействия процессов и содержит модуль IPCTHRD.PAS с аналогичными классами - для того же события, взаимного исключения (TMutex), а также совместно используемой памяти (TSharedMem).

Перейдем к подробному описанию объектов, используемых для синхронизации.

Событие

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

Класс TEvent (модуль SYNCOBJS.PAS) имеет два метода: SetEvent и ResetEvent, которые переводят объект в активное и пассивное состояние соответственно. Конструктор имеет следующий вид:

constructor Create (EventAttributes : PSecurityAttributes;
ManualReset, InitialState: Boolean;
const Name: string);

Здесь параметр Initialstate - начальное состояние объекта, ManualReset - способ его сброса (перевода в пассивное состояние). Если этот параметр равен True, событие должно быть сброшено вручную. В противном случае событие сбрасывается по мере того, как стартует хоть один поток, ждавший данный объект.

На третьем методе:

TWaitResult = (wrSignaled, wrTimeout, wrAbandoned, wrError);
function WaitFor (Timeout: EWORD) : TWaitResult;

остановимся подробнее. Он дает возможность ожидать активизации события в течение Timeout миллисекунд. Как вы могли догадаться, внутри этого метода происходит вызов функции WaitFotsingleObject. Типичных результатов на выходе waitFor два - wrsignaled, если произошла активизация события, и wrTimeout, если за время тайм-аута ничего не произошло.

(_Примечание_}

Если нужно (и допустимо!) ждать бесконечно долго, следует установить параметр Timeout в значение INFINITE.

Рассмотрим маленький пример. Включим в состав нового проекта объект типа TThread, наполнив его метод Execute следующим содержимым:

Var res: TWaitResult;
procedure TSimpleThread.Execute;
begin
e := TEvent.Create(nil,True, false, 'test');

repeat

e.ReSetEvent;
res := e.WaitFor(10000);
Synchronize(Showlnfo);

⇐ Предыдущая страница| |Следующая страница ⇒

Программирование в Delphi 7



Новости за месяц

  • Ноябрь
    2017
  • Пн
  • Вт
  • Ср
  • Чт
  • Пт
  • Сб
  • Вс