Многопотоковая обработка delphi

  • На форуме работает ручное одобрение пользователей. Это значит, что, если Ваша причина регистрации не соответствует тематике форума, а также Вы используете временную почту, Ваша учётная запись будет отклонена без возможности повторной регистрации. В дальнейшем - пожизненная блокировка обоих аккаунтов за создание мультиаккаунта.
  • Мы обновили Tor зеркало до v3!
    Для входа используйте следующий url: darkv3nw2...bzad.onion/
  • Мы вновь вернули telegram чат форуму, вступайте, общайтесь, задавайте любые вопросы как администрации, так и пользователям!
    Ссылка: https://t.me/chat_dark_time

AnGel

Администратор
Команда форума

AnGel

Администратор
Команда форума
27 Авг 2015
3,411
2,025
Пример: выполнить имитатор гонок (в просторечии эта задача известна как «тараканьи бега» ) при помощи создания нескольких потоков. Каждый поток обслуживает свою «беговую дорожку». На исполнение все потоки запускаются одновременно, после чего потоки произвольным образом приостанавливаются и запускаются вновь функциями SuspendThread() и ResumeThread().

На исполнение каждому потоку выделяется квант времени (например, 500 мс или 1 с). За этот период поток производит выполнение задачи, например, увеличивает позицию гонщика на некоторую величину. После истечения кванта времени поток приостанавливается на производный период времени, определяемый при помощи генератора случайных чисел.
После завершения гонки производиться выдача результатов(очередность завершения).
Завершение потока после завершения исполнения можно произвести при помощи функций ExitThread() и TerminateThread().

a3d4f533293c246d313ad216c542865f.png

Использование класса TThread, включенного в поставку interise Delphi или C++ Builder, допускается в ознакомительных целях.


Сделал вот так, на счет 100% правильности конечно говорить не приходиться, но думаю, что правильно. Кто ни чего не делает то не ошибается))

Код:
unit unitMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

const
  PROGRESS_POS = WM_USER+1;//установка значения
  EXITTHREAD_MESSAGE=WM_USER+2;//выход из потока
type
  TfrmMain = class(TForm)
    ProgressBar1: TProgressBar;
    ProgressBar2: TProgressBar;
    ProgressBar3: TProgressBar;
    ProgressBar4: TProgressBar;
    ProgressBar5: TProgressBar;
    btnStart: TButton;
    btnStop: TButton;
    btnClear: TButton;
    btnExit: TButton;
    Memo1: TMemo;
    Label1: TLabel;
    procedure btnStartClick(Sender: TObject);
    procedure btnStopClick(Sender: TObject);
    procedure btnClearClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure btnExitClick(Sender: TObject);
  private
    { Private declarations }
    procedure SetProgressPos(var Msg: TMessage); message PROGRESS_POS;
    procedure MSExitThread(var Msg: TMessage); message EXITTHREAD_MESSAGE;
  public
    { Public declarations }
  end;

  //процедура выполняемая в отдельном потоке
  procedure procedurePotoc1(aValue:PInteger);stdcall;
const
  countThread=5;//кол-во потоков

var
  frmMain: TfrmMain;
  thread:array[1..countThread] of THandle;//массив для хранения
  threadID:array[1..countThread] of DWORD;
  bStop,vse:Boolean;
  Poriadok:TStringList;
implementation

{$R *.dfm}
//процедура выполняемая в отдельном потоке
procedure procedurePotoc1(aValue:PInteger);stdcall;
var
  i:Integer;
begin
  for I := 0 to 100 do
  begin
    Randomize;
    Sleep(Random(100)+50);
    SendMessage(frmMain.Handle,PROGRESS_POS, aValue^, i);
  end;
  SendMessage(frmMain.Handle,EXITTHREAD_MESSAGE, aValue^, 0);
end;

procedure TfrmMain.btnClearClick(Sender: TObject);
var
  i:Integer;
begin
  for i := 1 to countThread do
  begin
    if thread[i]>0 then //проверка того, что он вообще запускался))
      if TerminateThread(thread[i],0) then
        thread[i]:=0;
  end;
  ProgressBar1.Position:=0;
  ProgressBar2.Position:=0;
  ProgressBar3.Position:=0;
  ProgressBar4.Position:=0;
  ProgressBar5.Position:=0;
  Poriadok.Clear;
  Memo1.Lines.Clear;
end;

procedure TfrmMain.btnExitClick(Sender: TObject);
begin
  frmMain.Close;
end;

procedure TfrmMain.btnStartClick(Sender: TObject);
var
  i:Integer;
  n:Integer;
begin
  for i := 1 to countThread do
  begin
    if thread[i]=0 then
    begin
      thread[i]:=CreateThread(nil,0, @procedurePotoc1, @thread[i], 0, threadID[i]);
    end;
    if (thread[i] = 0) then
      ShowMessage('Поток не создан '+IntToStr(i));
  end;
  Poriadok.Clear;
end;

procedure TfrmMain.btnStopClick(Sender: TObject);
var
  i:Integer;
begin
  for i := 1 to countThread do
  begin
    if bStop then
    begin
      ResumeThread(thread[i]);
    end
    else
    begin
      SuspendThread(thread[i]);
    end;
  end;
  if bStop then
    bStop:=False
  else
    bStop:=True;
end;

procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  btnClearClick(Self);
  Poriadok.Free;
end;


procedure TfrmMain.FormCreate(Sender: TObject);
begin
  Poriadok:=TStringList.Create;
end;

procedure TfrmMain.MSExitThread(var Msg: TMessage);
var
  i:Integer;
  temp:cardinal;
begin
  temp:=0;
  for I := 1 to countThread do
  begin
    if thread[i]=Msg.WParam then
    begin
      thread[i]:=0;
      Poriadok.Add('"Таракан" №'+IntToStr(i));
    end;
    temp:=temp+thread[i];
    if temp=0 then//все потоки завершились или нет
      vse:=True
    else
      vse:=False;
  end;
  if vse then//все потоки завершились или нет
    Memo1.Lines:=Poriadok;
end;

procedure TfrmMain.SetProgressPos(var Msg: TMessage);
var
  i:Integer;
  n:Integer;
  hN:THandle;
begin
  for i:= 1 to countThread  do
  begin
    if thread[i]=Msg.WParam then
      TProgressBar(Self.FindComponent('ProgressBar'+IntToStr(i))).Position:=Msg.LParam;
  end;
end;
end.
Синхронизацию с VCL реализовал путем обмена сообщениями.

Скачать:
Пожалуйста, Вход или Регистрация для просмотра содержимого URL-адресов!
 

О нас

  • Наше сообщество существует уже много лет и гордится тем, что предлагает непредвзятое, критическое обсуждение различных тем среди людей разных слоев общества. Мы работаем каждый день, чтобы убедиться, что наше сообщество является одним из лучших.

    Dark-Time 2015 - 2022

    При поддержке: XenForo.Info

Быстрая навигация

Меню пользователя