zoukankan      html  css  js  c++  java
  • TThread类详解<转>

    TThread是一个抽象类,可以创建几个独立的线程。
    类关系 TObject
    在一个多线程的应用程序中创建一个TThread的后子类代表一个线程。每一新子类的TThread对象的实例是一个新的线程。从TThread派生的多线程
    实例可以构成Delphi的多线程应用程序。
      当一个应用程序运行时,应用程序就被载入内存准备执行。此时,它成为包含一个或多个线程的进程,每个线程含有数据、代码和系统资
    源。线程执行应用程序的部分内容,并由系统分配CPU时间。同一进程的所有线程共享同一地址空间,可以访问进程的全局变量。线程通过以下工
    作改善应用的性能:管理多通信设备的输入。
      区分任务的优先级。优先级高的处理紧急的任务。优先级低的处理其他任务。
      以下是使用线程的一些建议:
      同时跟踪太多的线程消耗CPU时间。对单处理器系统,一个进程最多有16个线程。
      当多个线程更新相同的资源时,应使线程同步以避免冲突。
      大多数访问VCL对象和更新窗体的方法必须从主VCL线程内部调用。
    属性列表
    FreeOnTerminate 线程终止时该对象是否自动删除
    Handle 包含线程句柄
    Priority 确定该线程相对于进程中其他线程的优先级
    ReturnValue 返回线程值
    Suspended 指示一线程是否被挂起
    Terminated 表明线程被要求终止
    ThreadID 标识贯穿系统的线程
    方法列表
    ~TThread 删除线程对象并释放其战用的内存空间
    DoTerminate 产生一个OnTerminate事件
    Execute 提供包含线程执行时所需代码的抽象方法
    Resume 重新执行一个挂起的线程
    Suspend 挂起一个运行中的线程
    Synchronize 在主VCL线程中执行Method
    Terminate 将Ternimated属性设置为True通知线程终止
    TThread 创建一个线程对象的实例
    WaitFor 等待线程终止并返回ReturnValue属性值
    事件列表
    OnTerminateExecute 方法已返回且该线程被删除前发生
    属性
    property OnTerminate: TNotifyEvent;确定当线程终止时,该线程对象是否自动删除。
    FreeOnTerminate默认值为False,线程对象必须在代码中显示删除。
    包含线程句柄。
    当调用Win32API函数处理线程时,使用Handle.
    TThread::Priority
    __property TThreadPriority Priority = {read=GetPriority,write=SetPriority,nodefault};
    确定该线程相对于进程中其他线程的优先级。
    Priority属性为一枚举类型,其默认为tpNormal.
    TThreadPriority类型定义了TThread组件的Priority属性的可能值,如下表所述。Windows根据优先级确定每一个线程的CPU周期。
    _____________________________________________________________________
       值           含义
    _____________________________________________________________________
    tpIdle 只有当系统空闲时该线程执行
    tpLowest 线程优先级比正常低2点
    tpLower 线程优先级比正常低1点
    tpNormal 线程优先级为正常值
    tpHigher 线程优先级比正常高1点
    tpHighest 线程优先级比正常高2点
    tpTimeCritical 线程优先级最高
    TThread::ReturnValue
    __property int ReturnValue = {read=FReturnValue,write=FReturnValue,nodefault};
    返回线程值。
    使用ReturnValue应用为其他线程指示其成功/失败或数字结果/输出。WaitFor方法返回存储在ReturnValue中的值。
    TThread::Suspended
    __property bool Suspended = {read=FSuspended,write=SetSuspended,nodefault};
    指示一线程是否被挂起。
    除非重新执行,否则被挂起的线程不会继续执行。若将Suspended设置为True将挂起一个线程;若设置为False,则继续执行该线程。
    TThread::Terminated
    __property bool Terminated = {read=FTerminated,nodefault};
    表明线程被要求终止。Terminate方法将Terminated属性设置为True。
    线程的Execute方法和任何Execute调用的方法将周期性地检查Terminated,当其为True时,将终止执行。
    TThread::ThreadID
    __property int ThreadID = {read=FhreadID,nodefault};
    标识贯穿系统的线程。
    当调用Win32API函数处理线程时,ThreadID将十分有用。
    注意:ThreadID与Handle属性不同。
    方法
    TThread::~TThread
    __fastcall virvual ~TThread(void);
    删除线程对象并释放其战胜的内存空间。
    在应用中不要调用~TThread。用delete替代。
    ~TThread通知线程终止,并在调用Destroy方法前等待该线程返回。
    TThread::DoTerminate
    virtual void __fastcall DoTerminate(void);
    产生一个OnTerminate事件。
    DoTerminate调用OnTerminate时间句柄,但并不终止该线程。
    TThread::Execute
    virtual void __fastcall Execute(void) =0;
    提供包含线程执行时所需代码的抽象方法。
    Execute查看Terminated属性值以决定该线程是否需要终止。
    当CreateSuspended被设置为False,当调用Create时,一线程执行;在线程创建后先调用了Resume且CreateSuspended为True,一线程执行。
    注意:不要在线程的Execute方法中直接调用其他对象的属性和方法。应该将对其他对象的使用分成几个不同的过程,将其作为一个传递到
    Synchronize方法的参数分别调用。
    TThread::Resume
    void __fastcall Resume(void);
    重新执行一个挂起的线程。
    调用Suspend可以嵌套。因此调用Resume必须注意次序。
    TThread::Suspend
    void __fastcall Suspend(void);
    挂起一个运行中的线程。
    调用Resume可以继续运行。调用Suspend可以嵌套。因此调用Resume必须次序。
    TThread::Synchronize
    typedef void __fastcall(__closure* TThreadMethod)(void);
    void __fastcall Synchronize (TThreadMethod&Method);
    在主VCL线程中执行Method。
    Synchronize方法由Method指定的调用被主VCL线程执行。
    注意:当在主VCL线程中执行Method时,当前的线程被挂起。
    TThread::Terminate
    void __fastcall Terminate(void);
    通过将Terminated属性设置为True通知线程终止。
    线程的Execute方法以及Execute调用的任何方法应周期性的检查Terminated,当其为True时终止运行。
    TThread::TThread
    __fastcall TThread(bool CreateSuspended);
    创建一个线程对象的实例。
    在应用中不要直接使用TThread来创建线程。用new替代,传递CreateSuspended参数argument。若CreateSuspended为False,Execute被立即调用。若
    CreateSuspended为True,Execute直到Resume被调用后才被调用。
    TThread::WaitFor
    int __fastcall WaitFor(void);
    等待线程终止并返回ReturnValue属性值。
    直到线程终止时WaitFor才返回,因此线程一定是因为结束了Execute方法或因Terminated属性为了True而终止。如果该线程使用Synchronize,则不要
    在主VCL线程中调用WaitFor,否则或者引起系统死机,或者产生一个EThread异常。
    Synchronize在允许该方法生效前等待主VCL线程进入信息回路。若主VCL线程已经调用了WaitFor,它将不会进入信息回路,Synchronize也永远不会返
    回。此时,TThread将产生一个EThread意外并使该线程终止;而且如果该意外没有被Execute方法截获,该应用也将终止。如果调用WaitFor时,
    Synchronize已经在VCL线程中等待,TThread将不会干预,应用程序将死机。
    事件
    TThread::OnTerminate
    __property TNotifyEvent OnTerminate = {read=FOnTerminate,write=FOnTerminate};
    当线程的Execute方法已经返回且在该线程被删除之前发生。
    OnTerminate事件句柄在主VCL线程被调用。该线程对象也可在该事件中被释放。

     

    在是使用TThread时将会用到Classes单元中定义的9个函数,这9个函数为TThread提供同步管理

    下面就来分析一下,这几个函数,在函数中用到的几个单元变量

                           var
                            SyncList: TList = nil;//统计同时调用同步方法的线程对象
                            ThreadLock: TRTLCriticalSection;
                            ThreadCount: Integer;//统计进程中的线程数量

    1.InitThreadSynchronization

        这个函数功能是初始化临界区和创建事件对象

    procedure InitThreadSynchronization;
    begin
      InitializeCriticalSection(ThreadLock);//初始化临界区
      SyncEvent := CreateEvent(nil, True, False, '');//创建事件对象
      if SyncEvent = 0 then
        RaiseLastOSError;
    end;

    2.DoneThreadSynchronization

       这个函数的功能是销毁同步对象

    procedure DoneThreadSynchronization;
    begin
      DeleteCriticalSection(ThreadLock);//删除临界区
      CloseHandle(SyncEvent);//关闭事件对象
    end;

    3.ResetSyncEvent

       将SyncEvent置为无信号状态

    procedure ResetSyncEvent;
    begin

       ResetEvent(SyncEvent);
    end;

    4.WaitForSyncEvent(Timeout: Integer);
       在一定时间内,如果SyncEvent为有信号状态Reset SyncEvent

    procedure WaitForSyncEvent(Timeout: Integer);
    begin
      if WaitForSingleObject(SyncEvent, Timeout) = WAIT_OBJECT_0 then
        ResetSyncEvent;
    end;

    5.SignalSyncEvent

       置SyncEvent为有信号状态

    procedure SignalSyncEvent;
    begin
      SetEvent(SyncEvent);
    end;

    6.AddThread

    将ThreadCount加1,原子执行

    procedure AddThread;
    begin
      InterlockedIncrement(ThreadCount);
    end;

    7.RemoveThread

    将ThreadCount减1,原子执行

    procedure RemoveThread;
    begin
      InterlockedDecrement(ThreadCount);
    end;

    8.CheckSynchronize

      主线程对子线程同步,使得在多个子线程同时执行同步方法时,以循环的方式执行,只能在主线程中调用(1)

      主线程只有一个,子线程有多个,多个子线程同时调用同步方法是需要进行同步,用一个TList对象保存这写对象

     在TApplication.idle中被调用

    function CheckSynchronize(Timeout: Integer = 0): Boolean;
    var
      SyncProc: PSyncProc;
      LocalSyncList: TList;
    begin
      if GetCurrentThreadID <> MainThreadID then//(1)不是主线程就扔出一个异常
        raise EThread.CreateResFmt(@SCheckSynchronizeError, [GetCurrentThreadID]);
      if Timeout > 0 then
        WaitForSyncEvent(Timeout)
      else
        ResetSyncEvent;//所有等待线程将停止执行,
      LocalSyncList := nil;
      EnterCriticalSection(ThreadLock);//进入临界区,对SyncList和LocalSyncList进行保护,;
      try
        Integer(LocalSyncList) := InterlockedExchange(Integer(SyncList), Integer(LocalSyncList));

    // 交换Integer(SyncList), Integer(LocalSyncList));
        try
          Result := (LocalSyncList <> nil) and (LocalSyncList.Count > 0);
          if Result then
          begin
            while LocalSyncList.Count > 0 do
            begin
              SyncProc := LocalSyncList[0];
              LocalSyncList.Delete(0);
              LeaveCriticalSection(ThreadLock);
              try
                try
                  SyncProc.SyncRec.FMethod;//执行同步方法
                except
                  SyncProc.SyncRec.FSynchronizeException := AcquireExceptionObject;
                end;
              finally
                EnterCriticalSection(ThreadLock);
              end;
              SetEvent(SyncProc.signal);
            end;
          end;
        finally
          LocalSyncList.Free;
        end;
      finally
        LeaveCriticalSection(ThreadLock);
      end;
    end;

    9.线程函数,在CreateThread中将会使用,此函数间会调用Thread.Execute;

    function ThreadProc(Thread: TThread): Integer;
    var
      FreeThread: Boolean;
    begin
      try
        if not Thread.Terminated then
        try
          Thread.Execute;
        except
          Thread.FFatalException := AcquireExceptionObject;
        end;
      finally
        FreeThread := Thread.FFreeOnTerminate;
        Result := Thread.FReturnValue;
        Thread.DoTerminate;
        Thread.FFinished := True;
        SignalSyncEvent;
        if FreeThread then Thread.Free;
        EndThread(Result);
      end;
    end;

    本人新博客网址为:http://www.hizds.com
    本博客注有“转”字样的为转载文章,其余为本人原创文章,转载请务必注明出处或保存此段。c++/lua/windows逆向交流群:69148232
  • 相关阅读:
    BZOJ1527 : [POI2005]Pun-point
    2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016)
    2016-2017 ACM-ICPC Northwestern European Regional Programming Contest (NWERC 2016)
    NAIPC-2016
    BZOJ2498 : Xavier is Learning to Count
    ACM ICPC Vietnam National Second Round
    XVI Open Cup named after E.V. Pankratiev. GP of Ukraine
    XVI Open Cup named after E.V. Pankratiev. GP of Peterhof
    HDU5509 : Pattern String
    BZOJ4583 : 购物
  • 原文地址:https://www.cnblogs.com/zhangdongsheng/p/2221867.html
Copyright © 2011-2022 走看看