gpt4 book ai didi

multithreading - Delphi 10 : Correct way to run tasks simultaneously

转载 作者:行者123 更新时间:2023-12-03 19:13:09 29 4
gpt4 key购买 nike

我正在尝试学习如何使用delphi并行库而不是TThread。我有许多要同时运行的任务。每个任务最多都是在等待某个事件,而在等待时,我想将执行权传递给其他任务。
这是我的示例代码:

type

TObj = class
pos: integer;
Done: boolean;
Constructor Create;
procedure DoWork(Sender: TObject);
end;

var

Objects : array [0..39] of TObj;
tasks : array of ITask;

constructor TObj.Create;
begin
pos:=0;
DOne:=false;
end;

procedure TObj.DoWork(Sender: TObject);
begin
repeat
inc(pos);
sleep(100);
until Done;
end;

procedure TForm1.StartClick(Sender: TObject);
var
i: integer;
begin
Setlength (tasks ,Length(Objects));
for i:=0 to Length(tasks)-1 do begin
Objects[i]:=TObj.Create;
tasks[i] := TTask.Create(Objects[i],Objects[i].DoWork);
tasks[i].Start;
end;
sleep(5000);
Memo1.Lines.Clear;
for i:=0 to Length(tasks)-1 do begin
Objects[i].Done:=true;
Memo1.Lines.Add(IntToStr(Objects[i].pos));
end;
end;

我启动了N个任务,每个任务应在100毫秒内将其计数器增加1。然后我等待5秒钟,然后检查任务的值。我期望它们至少几乎相等,但是实际的Memo1的输出显示前12个值大约为50,其他4个值大约为20-30(我正在运行Ryzen 1600),我感到奇怪的是,最小的值都是0!

显然,在40秒中,至少有40个任务中有16个任务在5秒内一次被执行了,所以我想知道如何替换sleep(100)来将执行权实际传递给另一个任务?

最佳答案

仅仅因为您启动了N个任务,并不意味着N个任务将同时运行。如果需要,请坚持使用TThread

PPL使用内部线程池为TTask对象提供服务,并且该池根据您已安装的许多CPU和实际运行的任务数量进行自我调节。这在PPL documentation中进行了解释:

The RTL provides the Parallel Programming Library (PPL), giving your applications the ability to have tasks running in parallel taking advantage of working across multiple CPU devices and computers. The PPL includes a number of advanced features for running tasks, joining tasks, waiting on groups of tasks, etc. to process. For all this, there is a thread pool that self tunes itself automatically (based on the load on the CPU’s) so you do not have to care about creating or managing threads for this purpose.



如果创建的任务多于池中具有线程的任务,则某些任务将等待较早的任务完成其工作。当给定线程完成任务时,它将检查等待的任务,如果找到则运行该任务,然后重复进行直到没有其他任务可以运行为止。将其乘以池中的线程数和队列中的任务数。

因此,在任何给定时间都只会运行少量任务,因此可能要花一些时间才能完成所有排队的任务。

如果要对线程池进行更多控制,则必须创建一个 TThreadPool 对象,根据需要设置其 MinWorkerThreadsMaxWorkerThreads属性,然后将该对象传递给具有 TTask输入参数的 APool构造函数之一。默认情况下, MinWorkerThreads设置为 TThread.ProcessorCount,并且 MaxWorkerThreads设置为 TThread.ProcessorCount * 25

关于multithreading - Delphi 10 : Correct way to run tasks simultaneously,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45068750/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com