首页 > 解决方案 > Delphi的另一个单元中的多线程

问题描述

我在一个名为 Execution 的单元中有一个数字运算应用程序,它是从主窗体调用的。通常 Execution.pas 中的代码需要连续运行 10-15 次,我正在寻找一种应用多线程的有效方法,以便执行单元上的计算并行运行。代码的简化版本如下:

带有一个 Button1 的主窗体:

unit MainForm;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Execution;

type
  TMainForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;

var
  MainForm1: TMainForm1;

implementation

{$R *.dfm}

procedure TMainForm1.Button1Click(Sender: TObject);
var
  ExecutionThread: TThread;
  run_ID: integer;
begin
    for run_ID := 0 to 2 do
    begin
        ExecutionThread := TThread.CreateAnonymousThread(
        procedure
        begin
            Execution.CalculateSum;
        end);
        ExecutionThread.FreeOnTerminate := true;
        ExecutionThread.Start;
    end;
end;

end.

Execution.pas 单位:

unit Execution;

interface
uses System.SysUtils, Vcl.Dialogs;

  procedure CalculateSum;
  procedure IncrementSum(var Sum: integer);

implementation

const
  NoOfTimes = 100;
var
  Sum: integer;

procedure CalculateSum;
var
  i: integer;
begin
    Sum := 0;
    for i := 0 to Pred(NoofTimes) do
    begin
        IncrementSum(Sum);
    end;
    ShowMessage('Sum = ' + IntToStr(Sum));
end;

procedure IncrementSum(var Sum: integer);
begin
    Inc(Sum);
    Sleep(10);
end;

end.

如果我执行简化的代码,我会收到三条消息,总和接近 300,但不是 300(285、287、289),这是预期的,因为所有线程同时更改相同的全局变量 Sum,有时还会更改增量重叠。

有没有一种简单的方法可以为每个线程分配不同的内存,以便我得到三条总和为 100 的消息?还是我必须自己硬编码,在每个线程中分配不同的执行变量?

请注意,我拥有的原始应用程序包含数千个变量和记录,因此我正在寻找一种快速的方法来执行此操作而不会显着更改代码(当然,如果有的话)。

先感谢您。

标签: multithreadingdelphi

解决方案


你有没有想过使用TCriticalSectionin System.SyncObjs

一次只能有一个线程进入TCriticalSection,所以如果一个线程进入,修改共享变量,然后离开,那么每个线程都会等待其他线程。

如果您将大部分时间花在 TCriticalSection 中,这将无法帮助您进行扩展,因为您的线程将主要等待对象,但它确实确保一次只有一个线程正在修改受 TCriticalSection 保护的数据。

因此,如果您的代码不断更新共享变量,这将阻止它们发生冲突,但不会真正提供单独线程的好处。但是,如果线程在不修改变量的情况下进行大量计算,那么这允许该代码并行执行。


推荐阅读