【发布时间】:2014-07-21 09:59:23
【问题描述】:
我有以下场景:
我正在编写的程序模拟多个空中网络。现在我已经编写了它,以便每个模拟都在自己的线程中使用自己的数据。这样就不会污染数据,并且每个线程都是完整的多任务安全。我已经为每个线程实现了 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
我创建它们全部暂停的原因是因为我将它们存储在一个数组中,并且在我开始它们之前,我首先创建了工人及其属性。我正在模拟空中网络场景。每个解决方案都是不同的布局,而每个工作人员是运行该布局的不同方式。
我必须先计算所有工作人员的启动属性,然后再启动它们。事后看来,我可以修改代码以在线程中执行此操作。它目前发生在主线程中。线程的创建发生在我粘贴在这里的一段代码之前。
我将它们全部保留在线程中的原因是我需要评估每个线程的结果。
【问题讨论】:
-
大概问题的答案可以在代码中找到。
-
我添加了一些代码。我试图只添加我认为有必要保持简短的部分。请告诉我您是否需要其他一些代码。
-
谢谢,您的编辑保存了您的问题!
-
我认为这与我电脑上的 4 个本机线程有关
-
@DavidHeffernan 是的,我知道。我想说的是基于任务的方法的作用,将是我的场景的理想选择。我只是对 Delphi 中不受支持的第三方库有过不好的经历。而且我已经看到 OTL 已经不支持 3 个最新的 Delphi 版本了。
标签: multithreading delphi