delphi 一个简单的线程池类 已经初步完善

本文介绍了一个使用Delphi实现的简单线程池类,具备暂停、继续、退出任务等功能。线程池可以添加任务、管理任务状态,并提供了任务运行数量、已完成数量等信息。线程池的管理包括添加任务、开始执行、暂停、继续、清空任务等操作,同时具备任务执行完成后的消息通知机制。
摘要由CSDN通过智能技术生成

unit UntThreadpool;
{
  线程池单元
  每个线程的实现功能
    1  暂停 : 通过等待暂停事件 进行暂停 线程挂起会造成死锁
    2  继续 :通过等待事件继续
    3  直接退出线程 不继续执行
    4  退出当前的过程加载下一个任务过程  
  运行任务得到如下信息:
   1 当前正在运行的数量
    2  已经完成的数量
    3 一共任务的数量 
    4  清空正在运行的任务
  线程池的管理功能
    1 添加任务
       添加到任务队列中
       任务的总数量  := 任务的总数量  + 1 ;
    2 开始执行任务
    3 暂停任务
    4 继续任务
    5 清空当前的任务 准备接受新的任务
       任务的总数量  = 0     SumWorkCount
       正在运行的任务数量 = 0 RuningworkCount
       运行成功的任务 = 0     EndokWorkCount
       运行失败的任务 = 0     EndErrorWorkcount
       已经完成的任务数量 = 运行成功地任务 + 运行失败的任务 (因此 运行有一个返回值 True 运行成功  False 运行失败);
       剩余的任务数量 = 0     RemnantWorkCount
       任务信号量  重置信号量

       暂停所有任务
       重置信号量
       所有的数量置零
       设置退出任务  //未来保证所有的 资源在退出的时候也能够安全的释放
                     // 需要work执行三个过程
                       initwork  //初始化资源的过程用来 在执行前创建需要的资源
                       ExecWork  //具体的执行过程 退出当前的过程就是这个过程
                       FreeWork  //用来释放 创建的资源 即使过程退出也能安全的释放资源
       继续运行所有的线程 用来完成当前的任务

       剩余的任务数量 = 任务的总数量  - 正在运行的任务数量  - 已经完成的任务数量
    6 从任务队列中获得一个任务
        正在运行的任务数量 := 正在运行的任务数量 + 1
    7 完成的任务
        已经完成的任务数量 := 已经完成的任务数量 + 1
        如果运行成功
          运行成功的任务 := 运行成功的任务 +1 
       否则
        运行失败的任务 := 运行失败的任务 + 1
   
}
interface
uses
  classes ,SyncObjs ,Windows, UntKernel ,UntMsgClass ,Messages, Dialogs;
const
  //默认创建线程的数量
  CDefThreadcount = 1 ;
  //等待线程超时时间
  CWaitOutTime  = 10 * 1000 ;

  //任务执行完的消息
  WM_AllWorkEnd = WM_USER + 1000 ;
  //任务执行完但是有错误
  WM_AllWorkEndError = WM_USER + 1001 ;
Type
  {任务所在的状态}
  TWorkState =  (twsIdle{空闲} ,twsRun {运行}, twsStop {停止}, twsPause {暂停}) ;
  TWorkPoolState =  (twpIdle{空闲} ,twpRun {运行}, twpStop {停止}, twpPause {暂停}) ;
  TThreadState =  (ttsIdle{空闲} ,ttsRun {运行}, ttsStop {停止}, ttsPause {暂停} , ttsend {完成} ) ;
  //0 刚起动  1 正在下载  2 下载完成没有错误 3 下载完Down成有错误 4 用户停止了任务
  TItemRunState = (idsStart ,idsRuning, idsRunEndOk ,idsRunEndError ,idsExitWork);
  //线程操作的状态
  TThreadOperateState = (ttosGeneral {普通的状态} ,  ttosTerminate {结束并退出}, ttosExit {退出当前的过程});
  TThreadOperateStateSet = set of  TThreadOperateState ;

  TThreadPoolState =  (ttpIdle{空闲} ,ttpRun {运行}, ttpStop {停止}, ttpPause {暂停}) ;

  TWork = class ;
  TWorkPool = class ;
  TThreadPool = class ;
  TThreadWork = class ;
  //线程的处理集体过程
  TProcessRequest = procedure(Thread: TThreadWork) of object;


  //用来执行具体任务的工作线程
  TThreadWork = class(TThread)
  private
    FThreadPool : TThreadPool ;
    //当前线程状态
    FThreadState : TThreadState ;
    //
    FThreadOperateState : TThreadOperateStateSet ;
    //要执行的对象
    FProcessingWork : TWork ;
    //当前系统是否暂停
    FIsThreadPause : Boolean ;
    function GetExitWork: Boolean;
    procedure SetExitWork(const Value: Boolean);
    function GetTerminate: Boolean;
    procedure SetTerminate(const Value: Boolean);
    function GetIsRunging: Boolean;
  public
    property ThreadState : TThreadState Read  FThreadState ;
    property IsThreadPause : Boolean REad FIsThreadPause Write FIsThreadPause ;
    property IsExitWork : Boolean  Read GetExitWork  Write SetExitWork ;
    property IsTerminate : Boolean Read GetTerminate Write SetTerminate ;
    property IsRuning : Boolean Read GetIsRunging ;
    property ProcessingWork : TWork Read  FProcessingWork ;
    procedure Execute; override;
    constructor Create(AThreadPool : TThreadPool ;IsSuspend : Boolean  );
  end ;

 

  //线程池对象
  TThreadPool = class(TMSGClass)
  private
    FWorkPool : TWorkPool ;
    //线程列表
    FThreadList : TList;
    // 当前线程池状态
    FThreadPoolState : TThreadPoolState ;
    //初始化创建线程的数量
    FPoolCount : integer ;
    //判断是否有任务的信号量

    FSemaphoreRequest: TSemaphore;
    //事件内核对象用来停止所有的线程
    FEventThreadTerminated : TEvent ;

    //用来处理任务暂停的的事件
    FEventThreadPause : TEvent ;
    //创建是否挂起的线程池
    FIsSuspend : Boolean ;
    //是否立即结束当前任务
    FOnceEndAllWork : Boolean ;
    //
    FIsExitWork : Boolean ;
    //初始化线程池
    procedure initThreadPool ;
    //清除线程池
    procedure ClearPool ;

    procedure CancelExitwork ;

    //实现对完成任务的消息的处理
    procedure WmAllWorkEnd(var Message: TMessage); message WM_AllWorkEnd;
    procedure WMAllWorkEndError(var Message: TMessage); message WM_AllWorkEndError;
    function GetIsStop: Boolean;
  public
    property PoolCount : integer Read FPoolCount ;
    property  SemaphoreRequest : TSemaphore Read  FSemaphoreRequest ;
    property  EventThreadTerminated : TEvent Read FEventThreadTerminated ;
    property  OnceEndAllWork : Boolean Read FOnceEndAllWork ; //立即结束当前任务
    property  ThreadList : Tlist Read FThreadList ;
    property  IsStop : Boolean Read GetIsStop ;
    property  IsExitWork : Boolean Read FIsExitWork Write FIsExitWork ;

    procedure StartServer ; virtual ; //开始服务
    procedure StopServer  ; virtual ; //停止服务 所有的线程全部退出
    procedure StopWork ;    virtual ; //停止当前的任务 等待下一个任务的加入
    procedure PauseServer ; virtual ; //暂停服务
    procedure ContinueServer ; virtual ; //继续服务  -
    procedure ExitWork ;  virtual ; //退出当前执行的任务
    //重置线程池信息
    procedure ResetThreadPool ;

    //从队列中获得一个任务
    procedure GetListWork(var AWork : TWork ) ;


    constructor Create(AWorkPool : TWorkPool; APoolcount : integer = CDefThreadcount ; IsSuspend : Boolean = False  );
    destructor Destroy; override;
  end ;

  //用来执行的任务对象
  TWork = class
  private
    FWorkPool : TWorkPool ;
    FisEnd : Boolean  ;          //是否执行完毕
    FWorkState  : TWorkState ;
    FIsError : Boolean ;         //执行后是否出现错误 没有正常结束
  public
 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
delphi线程池单元文件uThreadPool.pas,用法如下 type TRecvCommDataWorkItem=class(TWorkItem) public // updatetime,addtime:TDateTime; // orderid,ordertype,urljson,loadcount,savepath:string; url,Filename:string; total,order:Integer; _orderid:string; failedcount:Integer; IFCoverFile:Boolean; // 线程处理请求时触发的事件 procedure DealwithCommRecvData(Sender: TThreadsPool; WorkItem: TWorkItem; aThread: TProcessorThread); // 线程初始化时触发的事件 procedure TProcessorThreadInitializing(Sender: TThreadsPool; aThread:TProcessorThread); // 线程结束时触发的事件 procedure TProcessorThreadFinalizing(Sender: TThreadsPool; aThread:TProcessorThread); //任务队列空时触发的事件 procedure TQueueEmpty(Sender: TThreadsPool; EmptyKind: TEmptyKind); end; 先声明一个 然后用法 FThreadPool := TThreadsPool.Create(nil); // 创建线程池 FThreadPool.ThreadsMin := 10; // 初始工作线程数 FThreadPool.ThreadsMax := 100; // 最大允许工作线程数 AWorkItem := TRecvCommDataWorkItem.Create; ISAllOverLoad:=False; AWorkItem.url:=urljson; AWorkItem.order:=i; AWorkItem.total:=JA.Count; AWorkItem.Filename:=savefilepath; AWorkItem._orderid:=orderid; AWorkItem.IFCoverFile:=IFCoverFile; FThreadPool.AddRequest(AWorkItem,True); // 向线程池分配一个任务 FThreadPool.OnProcessRequest := AWorkItem.DealwithCommRecvData; FThreadPool.OnThreadInitializing := AWorkItem.TProcessorThreadInitializing; FThreadPool.OnThreadFinalizing := AWorkItem.TProcessorThreadFinalizing; FThreadPool.OnQueueEmpty := AWorkItem.TQueueEmpty; 仔细看下线程池单元的函数说明轻松搞定。 procedure TRecvCommDataWorkItem.TQueueEmpty(Sender: TThreadsPool; EmptyKind: TEmptyKind); begin if EmptyKind=ekProcessingFinished then begin try if Assigned(geturl) then //存在的bug 如果下载文件存在的不行 begin //Sleep(200); //激活线程可能会发生在 休眠之前!! ISAl
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值