Сама идея:
Запустит несколько паралельных потоков для выполнения некой общей задачи, причем каждый поток должен получить свои параметры для работы.
Применение на будущее: например одновременно сканирование файлов в нескольких директориях, понятно что имя директории для сканирования для каждого потока должно быть свое. Хоть и алгоритм сканирования общий.
Демо: передача параметров через блокирующую коллекцию, использование параметров через record (обертка), передаются два параметра частота и длительность, функция выполняющаяся в потоке получает эти параметры и 10 раз проигрывает сигнал с такой частотой и длительностью.
Потоков на запуск 4, работают одновременно 2....
unit Main; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, OTLParallel, OtlTaskControl, OtlCollections, OtlCommon; type TParametersForProc = record Hz : Integer; Duration : Integer; end; TForm3 = class(TForm) Memo1: TMemo; Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } Join : IOmniParallelJoin; CollectionParams : IOmniBlockingCollection; public { Public declarations } procedure JoinProcExecute; end; var Form3: TForm3; implementation {$R *.dfm} procedure Go(Hz, Duration : Integer); var I: Integer; begin for I := 0 to 10 do begin Sleep(1000); Winapi.Windows.Beep(Hz, Duration); end end; procedure TForm3.JoinProcExecute; var Value : TOmniValue; ParamProc : TParametersForProc; begin // Взять из коллекции параметры CollectionParams.Take(Value); // Преобразовать обратно ParamProc := Value.Unwrap; // Запустить процедуру с переданными параметрами Go(ParamProc.Hz, ParamProc.Duration); // вывести параметры Memo1.Lines.Add(Format('Hz : %d; duration: %d',[ParamProc.Hz, ParamProc.Duration])); end; procedure TForm3.Button1Click(Sender: TObject); var arrayProc : array of TProc; I: Integer; Value : TOmniValue; ParamProc : TParametersForProc; begin CollectionParams := TOmniBlockingCollection.Create; SetLength(arrayProc, 4); for I := Low(arrayProc) to High(arrayProc) do begin // Для каждого потока свои параметры, поэтому перед запуском потоков // в коллекцию добавляем параметры, функция выполняющаяся в потоке будет // брать параметр для себя из коллекции ParamProc.Hz := (I+1) * 1000; ParamProc.Duration := (I+1) * 20; // обернуть рекорд к TOmniValue Value := TOmniValue.Wrap(ParamProc); // Добавим в параметры CollectionParams.Add(Value); arrayProc[i] := JoinProcExecute; end; CollectionParams.CompleteAdding; // добавление завершено // NumTasks(2) - два потока выполняются одновременно Join := Parallel.Join(arrayProc).NumTasks(2).NoWait.Execute; // запуск параллельных потоков end; end.
Дмитрий, у меня есть к Вам несколько вопросов по OTL, как с Вами связаться? Василий rum @ craocrimea.ru
ОтветитьУдалить