gpt4 book ai didi

multithreading - Delphi并非所有线程同时执行

转载 作者:行者123 更新时间:2023-12-03 18:01:53 27 4
gpt4 key购买 nike

我有以下情况:

我正在编写的程序模拟了多个空中网络。现在,我已经编写了它,以便每个模拟都在其自己的线程中具有自己的数据。这样一来,就不会有数据污染,并且每个线程都是完全安全的多任务处理程序。我已经为每个线程实现了delphi的本地TThread类。

该程序有一个主线程。然后,它为每个网络创建多个子线程(我当前的测试用例有6个)。但是每个子线程还具有4个附加线程,因为其网络具有多个布局。因此,我总共有31个线程,但是只有24个线程正在积极处理。所有线程都是在挂起模式下创建的,因此我可以手动启动它们。

我运行的计算机是i5笔记本电脑,因此它具有4个线程(2个物理核心+ 2 HT)。在生产环境中,它将在服务器上运行,因此它们将具有更大的处理能力。

现在,在主程序线程中,我在执行线程的for循环之后添加了一个断点。这不会立即触发。看着Delphi的调试控制台,看起来它一次只在运行4个线程。一旦退出,它将启动另一个线程。

线程中的仿真难以优化,并且需要一些循环才能完成仿真。每个循环都需要前一个循环的数据。但是每个模拟都完全独立于下一个模拟,因此该程序是线程和管道衬里的理想选择。

现在我的问题是,为什么它只启动4个线程而不是代码指定的所有线程?

编辑添加了几段代码

主程序

    for i := 0 to length(Solutions)-1 do
begin
Solutions[i].CreateWorkers; //Setup threads
end;
for i := 0 to length(Solutions)-1 do
begin
Solutions[i].Execute; //start threads
end;
end;

isSolversBusy := false; //breaking point doesn't trigger here

第一级线程
procedure cSolution.Execute;
var
i : integer;
lIsWorkerStillBusy : boolean;
begin
lIsWorkerStillBusy := true;
for i := 0 to length(Workers)-1 do
begin
Workers[i].Start;
end;
while (lIsWorkerStillBusy) do
begin
lIsWorkerStillBusy := false;
for i := 0 to length(Workers)-1 do
begin
if Workers[i].IsCalculated = false then
begin
lIsWorkerStillBusy := true;
end;
end;
sleep(100);
end;
FindBestNetwork;
IsAllWorkersDone := true;
end;

第二级线程
procedure cWorker.Execute;
begin
IsCalculated := false;
Network.UpdateFlows;
Network.SolveNetWork; //main simulation work
CalculateTotalPower;
IsCalculated := true;
end;

编辑2

之所以将它们全部暂停是因为我将它们存储在一个数组中,并且在启动它们之前,我首先创建了worker及其属性。我正在模拟空中网络场景。每个解决方案都是不同的布局,而每个工作人员都是运行该布局的不同方法。

我必须先计算所有工作程序的启动属性,然后再启动它们。事后看来,我可以修改代码以在线程中执行此操作。它当前发生在主线程中。线程的创建发生在我在此处粘贴的代码段之前。

我将它们全部保留在线程中的原因是,我需要评估每个线程后缀的结果。

最佳答案

这是你的问题 :

for i := 0 to length(Solutions)-1 do
begin
Solutions[i].Execute; //start threads
end;

这不会启动线程-这是在调用线程中执行 Execute方法。实际上,您一次并不会只运行4个线程,甚至没有运行一个线程-所有这些工作将依次在主线程上完成。要恢复挂起的线程,必须使用 Solutions[i].Start
ExecuteTThread方法是一种特殊方法,该方法在由 TThread自动创建的工作线程上执行。当您创建 TThread时,此方法会自动在 TThread创建的工作线程上运行。如果您将线程创建为暂停状态,则它仅在开始工作之前等待您唤醒线程。调用 .StartTThread方法即可实现此目的-触发基础工作线程开始执行 .Execute方法。

否则, Execute方法以及 TThread的所有其他方法与属于该类的任何其他常规方法没有什么不同。它们可以在直接调用它们的任何线程上执行。

在这种情况下,您似乎并没有在创建和执行工作程序之间的主线程中做任何其他工作。在这种情况下,除非您有明确的需求,否则您可以简单地创建未暂停的线程,并让它们在创建时自动执行。

关于multithreading - Delphi并非所有线程同时执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24862359/

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