我在程序中需要用到多线程去取数据,但是我发觉开多个线程比开多个应用程序要慢的多,大家看看我的线程代码是否有问题?unit FlightThread;interfaceuses
  WinProcs,Classes,Graphics,ExtCtrls,ComCtrls,StdCtrls,Forms,SysUtils,DateUtils,CommonFunc,DataModule;type
  TFlightThread1 = class(TThread)
private
   FProgress:TProgressBar;
   FStatus  :TLabel;
   FMemoLog :TMemo;
   FCurIndex   :Integer;
   FCurDays    :Integer;
   FDays       :Integer;
   FDownMinu   :Integer;
   FFlightList :Tstrings;
   FFlag       :string;
   procedure PowerAVData;
protected
   procedure   Execute;override;
public
   constructor Create(Suspended:Boolean;Progress:TProgressBar;MemoLog:TMemo;Status:TLabel;FlightList:TStrings;DownDays:Integer;DownMinu:Integer;Flag:String);
end;implementationconstructor TFlightThread1.Create(Suspended:Boolean;Progress:TProgressBar;MemoLog:TMemo;Status:TLabel;FlightList:TStrings;DownDays:Integer;DownMinu:Integer;Flag:string);
begin
  inherited Create(Suspended);
  FProgress:=Progress;
  FStatus  :=Status;
  FMemoLog :=MemoLog;
  FCurIndex   :=0;
  FCurDays    :=1;
  FDays       :=DownDays;
  FDownMinu   :=DownMinu;
  FFlightList :=FlightList;
  FreeOnTerminate:=True;
  FFlag       :=Flag;
  if (FFlag='') Then FFlag:='1';
end;procedure TFlightThread1.PowerAVData;
    //处理数据
    Sleep(1);
    Application.ProcessMessages;
end;procedure TFlightThread1.Execute;
begin
  repeat
     Synchronize (PowerAVData);
     Sleep(200);
  until Terminated;
end;end.

解决方案 »

  1.   

    跟Sleep(200)有一定的关系
    "慢得多"不知何,不是取海量数据,应该慢不了多少.
    个人见解
    听楼下的
      

  2.   

    传递界面元素,然后在线程中直接访问的方法是不可取的。
    FProgress:TProgressBar;  错误
       FStatus  :TLabel;错误
       FMemoLog :TMemo;错误传递一个界面的HANDLE,需要让在界面上显示的时候发送一个消息,用Postmessage
    until Terminated; 这是干吗???
    要让线程自然结束,不要强制释放。Application.ProcessMessages;  这又是在做什么??
    你不是用了线程吗?怎么还想用这样的方式呢??你能保证 FlightList 对象在线程执行的时候其它线程不访问他吗??
    如果不能,则要不访问FlightList它的时候同步,要不创建FFlightList实例,然后
    读取FlightList的数据。
      

  3.   

    乱七八糟的问题我就不说了,谈谈你说的那个慢的问题吧,首先,多线程并不一定就比单一线程要快,尤其是在你只有一个CPU的时候。你说的慢,我猜测应该不是数据处理慢,而是界面反馈慢,换句话说,就是数据完成了处理,但界面没有即使完成信息的反馈(看你的线程中有关于界面的东西),那么问题可能在这里Synchronize (PowerAVData);Synchronize 的作用是在主线程中执行一个方法。当你在程序中第一次创建一个附属线程时, V C L将会从主线程环境中创建和维护一个隐含的线程窗口。此窗口唯一的目的是把通过Synchronize 调用的方法排队。
    Synchronize 把由Method参数传递过来的方法保存在TThread的FMethod字段中,然后,给线程窗
    口发一个CM_EXECPROC消息,并且把消息的lParam参数设为self(这里指线程对象)。当线程窗口的窗口过程收到这个消息后,它就调用FMethod字段所指定的方法。由于线程窗口是在主线程内创建的,线程窗口的窗口过程也将被主线程执行。因此, FMethod字段所指定的方法就在主线程内执行。你的代码中 ,PowerAVData完成数据处理,而此函数又通过Synchronize 放在主线程中执行,换句话说,你所谓的多线程处理数据,最终用来处理数据的东西还是都在主线程中执行的。也就是说,你这么写和用一个主线程来完成操作没有多大区别。。当你开了多个这样的线程的时候,数据处理以及和VCL界面的同步有可能出现一些问题,让你的程序看起来很慢。然后,你使用sleep(200),他意味着你的线程立即放弃CPU,并且在200毫秒之内不会被调用,但不保证200毫秒之后一定被调用。   而当你使用多个进程的时候,自然也就代表了多个线程,他们分别抢占CPU完成数据处理并进行界面的反馈。建议: 多了解一下WIN32平台的多线程机制,然后再尝试使用它,如果不熟悉就贸然使用,反而会带来负面效果。另外,VCL中TThread对象的Synchronize 方法主要是为了和VCL界面同步所设计的,它并不是真正意义上实现多线程抢占CPU完成数据处理的方法,作为一些简单的应用,那些和界面无关的部分,无需放在它里边执行,如果数据处理涉及到同步,在单一进程中,可以考虑使用临界区,如果多个进程可以考虑使用互斥对象。