Читаем Фундаментальные алгоритмы и структуры данных в Delphi полностью

aSyncObj : TtdProduceManyConsumeSync;

aBuffers : TQueuedBuffers);

end;

constructor TProducer.Create(aStream : TStream;

aSyncObj : TtdProduceManyConsumeSync;

aBuffers : TQueuedBuffers);

begin

inherited Create (true);

FStream := aStream;

FSyncObj := aSyncObj;

FBuffers := aBuffers;

end;

procedure TProducer.Execute;

var

Tail : PBuffer;

begin

{выполнять до тех nop, пока поток не будет исчерпан...}

repeat

{передать сигнал о готовности к началу генерации данных}

FSyncObj.StartProducing;

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

Tail := FBuffers.Tail;

Tail74.bCount := FStream.Read (Tail^.ЬВ1оск, 1024);

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

FBuffers.AdvanceTail;

{передать сигнал о прекращении генерации данных}

FSyncObj.StopProducing;

until (Tail^.bCount = 0);

end;

type

TConsumer = class (TThread) private

FBuffers : TQueuedBuffers;

FID : integer;

FStream : TStream;

FSyncObj : TtdProduceManyConsumeSync;

protected

procedure Execute; override;

public

constructor Create(aStream : TStream;

aSyncObj : TtdProduceManyConsumeSync;

aBuffers : TQueuedBuffers;

alD : integer);

end;

constructor TConsumer.Create(aStream : TStream;

aSyncObj : TtdProduceManyConsumeSync;

aBuffers : TQueuedBuffers;

alD : integer);

begin

inherited Create (true);

FStream := aStream;

FSyncObj := aSyncObj;

FBuffers := aBuffers;

FID := alD;

end;

procedure TConsumer.Execute;

var

Head : PBuffer;

begin

{передать сигнал о готовности к началу потребления данных}

FSyncObj.StartConsuming(FID);

{выполнить считывание начального буфера очереди}

Head := FBuffers.Head[FID];

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

while (Head^.bCount <> 0) do

begin

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

FStream.Write(Head^.bBlock, Head^.bCount);

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

FBuffers.AdvanceHead(FID);

{обработка этого буфера завершена}

FSyncObj.StopConsuming(FID);

{передать сигнал о повторной готовности к началу потребления данных}

FSyncObj.StartConsuming(FID);

{выполнить считывание начального буфера очереди}

Head := FBuffers.Head[FID];

end;

{обработка последнего буфера завершена}

FSyncObj.StopConsuming(FID);

end;

И, наконец, рассмотрим подпрограмму копирования потоков, код которой показан в листинге 12.21.

Листинг 12.21. Копирование потоков с применением модели "производитель-потребитель"

procedure ThreadedMultiCopyStream(aSrcStream : TStream;

aDestCount : integer;

aDestStreams : PStreamArray);

var

i : integer;

SyncObj : TtdProduceManyConsumeSync;

Buffers : TQueuedBuffers;

Producer : TProducer;

Consumer : array [0..pred(MaxConsumers) ] of TConsumer;

WaitArray : array [0..MaxConsumers] of THandle;

begin

SyncObj nil;

Buffers nil;

Producer :=nil;

for i := 0 to pred(MaxConsumers) do

Consumer[i] := nil;

for i := 0 to MaxConsumers do

WaitArray[i] := 0;

try

{создать объект синхронизации}

SyncObj : * TtdProduceManyConsumeSync.Create(20, aDestCount);

{создать объект буфера с очередью}

Buffers := TQueuedBuffers.Create(20, aDestCount);

{создать поток производителя и сохранить его дескриптор}

Producer := TProducer.Create(aSrcStream, SyncObj, Buffers);

WaitArray[0] := Producer.Handle;

{создать потоки потребителей и сохранить их дескрипторы}

for i := 0 to pred(aDestCount) do

begin

Consumer [ i ] := TConsumer.Create(

aDestStreams^[i], SyncObj, Buffers, i);

WaitArray[i+1] := Consumer[i].Handle;

end;

{запустить потоки}

for i := 0 to pred(aDestCount) do

Consumer[i].Resume;

Producer.Resume;

{ожидать завершения потоков}

WaitForMultipleObjects(l+aDestCount, @WaitArray, true, INFINITE);

finally Producer.Free;

for i := 0 to pred(aDestCount) do

Consumer[i].Free;

Buffers.Free;

SyncObj.Free;

end;

end;

Большая часть кода предназначена для выполнения тех же рутинных задач, что и в модели с одним потребителем, представленной в листинге 12.14, за исключением того, что на этот раз необходимо заботиться о нескольких потребителях. Полный код подпрограммы находится в файлах TstNCpy.dpr и TstNCpyu.pas на Web-сайте издательства, в разделе материалов.

<p>Поиск различий между двумя файлами</p>

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

Существует множество программ, выполняющих подобные функции. В их числе и программа diff, которую можно считать прародительницей всех программ сравнения файлов. Пакет Microsoft Windows SDK содержит программу, названную WinDiff. Программа Visual SourceSafe, поставляемая компанией Microsoft, также предоставляет функцию, которая позволяет выбрать две версии файла, хранящиеся в базе данных, и просмотреть различия между ними.

-------

Этот раздел адресован только тем программистам, которые работают в 32-разрядной среде. Рассмотренный здесь алгоритм является рекурсивным и интенсивно использует программный стек. Delphi1 не поддерживает достаточно большой стек, чтобы с его помощью можно было реализовать этот алгоритм даже для сравнительно умеренных по размеров файлов.

-------

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных