Вход/Регистрация
Фундаментальные алгоритмы и структуры данных в Delphi
вернуться

Бакнелл Джулиан М.

Шрифт:

Листинг 12.17. Методы StartConsuming и StopConsuming

procedure TtdProduceManyConsumeSync.StartConsuming(aId : integer);

var

ConsumerInfo : PConsumerInfo;

begin

{чтобы можно было начать потребление данных, потребителю с данным конкретным идентификатором должен быть передан семафор "имеются данные"}

ConsumerInfo := PConsumerInfo(FConsumerInfo[aId]);

WaitForSingleObject(ConsumerInfo^.ciHasData, INFINITE);

end;

procedure TtdProduceManyConsumeSync.StopConsuming(aId : integer);

var

BufInfo : PBufferInfo;

ConsumerInfo : PConsumerInfo;

NumToRead : integer;

begin

{мы выполнили считывание данных в буфере, на который указывает указатель начала очереди}

ConsumerInfo := PConsumerInfo(FConsumerInfo[aId]);

BufInfo := PBufferInfo(FBufferInfo[ConsumerInfo^.ciHead]);

NumToRead := InterLockedDecrement(BufInfo^.biToUseCount);

{переместить указатель начала очереди}

inc(ConsumerInfo^.ciHead);

if (ConsumerInfo^.ciHead >= FBufferCount) then

ConsumerInfo^.ciHead := 0;

{если данный поток был последним, который должен был использовать этот буфер, производителю нужно сигнализировать о необходимости генерирования новых данных}

if (NumToRead = 0) then

ReleaseSemaphore(FNeedsData, 1, nil);

end;

Конструктор и деструктор этого класса должны создавать и уничтожать большое количество объектов синхронизации, а также всю информацию о буфере и потребителе.

Листинг 12.18. Создание и уничтожение объекта синхронизации

constructor TtdProduceManyConsumeSync.Create(aBufferCount : integer;

aConsumerCount : integer);

var

NameZ : array [0..MAX_PATH] of AnsiChar;

i : integer;

BufInfo : PBufferInfo;

ConsumerInfo : PConsumerInfo;

begin

inherited Create;

{создать семафор "требуются данные"}

GetRandomObjName(NameZ, 'tdPMC.Needs Data');

FNeedsData := CreateSemaphore(nil, aBufferCount, aBufferCount, NameZ);

if (FNeedsData = INVALID_HANDLE_VALUE) then

RaiseLastWin32Error;

{создать циклическую очередь буферов и заполнить ее}

FBufferCount := aBufferCount;

FBufferInfo := TList.Create;

FBufferInfo.Count := aBufferCount;

for i := 0 to pred(aBufferCount) do

begin

New(BufInfo);

BufInfo^.biToUseCount :=0;

FBufferInfo[i] := BufInfo;

end;

{создать информационный список потребителей и заполнить его}

FConsumerCount := aConsumerCount;

FConsumerInfo := TList.Create;

FConsumerInfo.Count := aConsumerCount;

for i := 0 to pred(aConsumerCount) do

begin

New(ConsumerInfo);

FConsumerInfo[i] := ConsumerInfo;

GetRandomObjName(NameZ, 'tdPMC.HasData');

ConsumerInfo^.ciHasData :=

CreateSemaphore(nil, 0, aBufferCount, NameZ);

if (Consumer Info^.ciHasData = INVALID__HANDLE__VALUE) then

RaiseLastWin32Error;

ConsumerInfo^.ciHead := 0;

end;

end;

destructor TtdProduceManyConsumeSync.Destroy;

var

i : integer;

BufInfo : PBufferInfo;

ConsumerInfo : PConsumerInfo;

begin

{уничтожить семафор "требуются данные"}

if (FNeedsData <> INVALID_HANDLE_VALUE) then

CloseHandle(FNeedsData);

{уничтожить информационный список потребителей}

if (FConsumerInfo <> nil) then begin

for i := 0 to pred(FConsumerCount) do

begin

ConsumerInfo := PConsumerInfo(FConsumerInfo[i]);

if (ConsumerInfo <> nil) then begin

if (ConsumerInfo^.ciHasData <> INVALID__HANDLE__VALUE) then

CloseHandle(ConsumerInfo^.ciHasData);

Dispose(ConsumerInfo);

end;

end;

FConsumerInfo.Free;

end;

{уничтожить информационный список буферов}

if (FBufferInfo <> nil) then begin

for i := 0 to pred(FBufferCount) do

begin

BufInfo := PBufferInfo(FBufferInfo[i]);

if (BufInfo <> nil) then

Dispose(BufInfo);

end;

FBufferInfo.Free;

  • Читать дальше
  • 1
  • ...
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: