我运行一个多线程应用程序,我想限制我的机器上的线程数 代码概念目前就像这样(它只是一个显示背后主要思想的一个小道)
// a List with all the threads I have
class MyTHreadList = List<TMyCalcThread>;
// a pool class, check how many threads are active
// try to start additions threads once the nr. of running THreads
// is below the max_thread_value_running
class MyTheardPool = Class
ThreadList : MyTHreadList;
StillRunningTHreads : Integer;
StartFromThreadID : Integer;
end;
var aTHreadList : MyTHreadList;
procedure MainForm.CallCreateThreadFunction( < THREAD PARAMS > );
begin
// just create but do not start here
MyTHread := TMyCalcThread.create ( < THREAD PARAMS > );
MyTHread.Onterminate := What_To_do;
// add all threads to a list
aTHreadList.add(MyTHread);
end;
/// (A)
procedure MainForm.What_To_do ()
var start : Integer;
begin
max_thread_value_running := max_thread_value_running -1;
if max_thread_value_running < max_thread_count then
begin
start := max_thread_count - max_thread_value_running;
startThereads(start,StartFromThreadID)
end;
end;
procedure MainForm.startThereads (HowMany , FromIndex : Integer);
var i : INteger;
begin
for I := FromIndex to HowMany + FromIndexdo
begin
// thread[i].start
end;
end;
MainForm.Button ();
/// main VCL form , create threats
for i := 0 to allTHreads do
begin
CallCreateTHreadFunction( < THREAD PARAMS > );
end;
......
/// (B)
while StillRunningTHreads > 0 do
begin
Application.processmessages;
end;
完整的想法是一个包含线程的小列表,在每个单独的线程终止步骤中,我更新正在运行的线程的数量并启动现在可能的最大值。新线程的数量。(A)而不是函数WaitforSingleObject()....我在最后做一个循环来等待所有线程完成执行。 (B)
从代码设计中我没有在网上找到任何完整的例子,我可能接近一个虚拟设计或者我会遇到一些我现在没有考虑的麻烦。 欢迎任何关于设计或更好的班级设计的评论。
答案 0 :(得分:7)
不要试图微观管理这样的线程。只是不要。使用Win API线程池调用,或者从生产者 - 消费者队列和TThread实例创建自己的线程池。
当一项任务完成后,我建议工作线程调用一个&#39; OnCompletion&#39;任务类的TNotifyEvent,以任务作为参数。可以由任务的发布者将其设置为他们可能希望的任何内容,例如。 postMessaging任务实例到GUI线程显示。
微管理线程,不断创建/等待/终止/销毁,Application.processmessages循环等非常可怕,几乎肯定会在某些时候出错。
在GUI事件处理程序中等待任何事情都很糟糕。 GUI系统是状态机,您不应该在其中等待。如果您想从GUI线程发出任务,请执行此操作但不要等待它 - 将其关闭并忘记它直到完成并将其发回消息处理程序。
答案 1 :(得分:3)
基本上,线程池是一个不错的功能(Win32 API中有一个实现,但我没有任何经验)。
然而,有一个基本的绊脚石:您需要记住任务可能会延迟,直到空线程可用。如果您需要在不同任务之间进行同步(例如,任务正在等待其他任务),那么您就会遇到严重的死锁问题:
如果您的任务不需要任何进一步的同步(例如,一旦任务完成,它将只标记为已完成,主线程将在稍后读取结果),您不必担心这一点。 / p>
作为一个小旁注:
答案 2 :(得分:1)
循环(B)从线程中消耗了大量CPU能力。不要在循环中主动等待线程,使用WaitFor ....函数之一。
重用你的线程,并有一个线程将执行的“待办事项”列表。创建和销毁线程可能很昂贵。
除此之外,我建议您使用现有的库而不是重新发明轮子。或者至少使用Windows API线程池函数。