线程池类开发

时间:2014-06-27 07:01:54

标签: multithreading delphi

我运行一个多线程应用程序,我想限制我的机器上的线程数 代码概念目前就像这样(它只是一个显示背后主要思想的一个小道)

     //  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)

从代码设计中我没有在网上找到任何完整的例子,我可能接近一个虚拟设计或者我会遇到一些我现在没有考虑的麻烦。 欢迎任何关于设计或更好的班级设计的评论。

3 个答案:

答案 0 :(得分:7)

不要试图微观管理这样的线程。只是不要。使用Win API线程池调用,或者从生产者 - 消费者队列和TThread实例创建自己的线程池。

当一项任务完成后,我建议工作线程调用一个&#39; OnCompletion&#39;任务类的TNotifyEvent,以任务作为参数。可以由任务的发布者将其设置为他们可能希望的任何内容,例如。 postMessaging任务实例到GUI线程显示。

微管理线程,不断创建/等待/终止/销毁,Application.processmessages循环等非常可怕,几乎肯定会在某些时候出错。

在GUI事件处理程序中等待任何事情都很糟糕。 GUI系统是状态机,您不应该在其中等待。如果您想从GUI线程发出任务,请执行此操作但不要等待它 - 将其关闭并忘记它直到完成并将其发回消息处理程序。

答案 1 :(得分:3)

基本上,线程池是一个不错的功能(Win32 API中有一个实现,但我没有任何经验)。

然而,有一个基本的绊脚石:您需要记住任务可能会延迟,直到空线程可用。如果您需要在不同任务之间进行同步(例如,任务正在等待其他任务),那么您就会遇到严重的死锁问题:

  1. 假设所有正在运行的任务都在等待等待免费线程的单个任务......
  2. 如果您的线程在主线程等待新任务启动时等待主线程做出反应,也会发生类似的问题。
  3. 如果您的任务不需要任何进一步的同步(例如,一旦任务完成,它将只标记为已完成,主线程将在稍后读取结果),您不必担心这一点。 / p>

    作为一个小旁注:

    • 我会使用两个单独的列表:一个用于免费(暂停)线程,另一个用于运行线程。
    • 在创建自己的...之前,我会考虑使用现有的Thread-Pool实现(比如Winapi CreateThreadpool)...

答案 2 :(得分:1)

循环(B)从线程中消耗了大量CPU能力。不要在循环中主动等待线程,使用WaitFor ....函数之一。

重用你的线程,并有一个线程将执行的“待办事项”列表。创建和销毁线程可能很昂贵。

除此之外,我建议您使用现有的库而不是重新发明轮子。或者至少使用Windows API线程池函数。