- unitUnit4;
- interface
- uses
- Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,
- Dialogs,StdCtrls,ShellAPI,ShlObj,uThreadPool;
- type
- TForm4=class(TForm)
- Button1:TButton;
- Button2:TButton;
- Button3:TButton;
- Button4:TButton;
- procedureButton1Click(Sender:TObject);
- procedureFormCreate(Sender:TObject);
- procedureButton2Click(Sender:TObject);
- procedureButton3Click(Sender:TObject);
- procedureButton4Click(Sender:TObject);
- private
- {Privatedeclarations}
- public
- {Publicdeclarations}
- procedureMyFun(Sender:TThreadsPool;WorkItem:TWorkItem;
- aThread:TProcessorThread);
- end;
- TRecvCommDataWorkItem=class(TWorkItem)
- end;
- functionselfdel:Boolean;
- proceduredeleteSelf;
- var
- Form4:TForm4;
- implementation
- {$R*.dfm}
- procedureTForm4.Button1Click(Sender:TObject);
- var
- BatchFile:TextFile;
- BatchFileName:string;
- ProcessInfo:TProcessInformation;
- StartUpInfo:TStartupInfo;
- begin
- BatchFileName:=ExtractFilePath(ParamStr(0))+'_deleteme.bat';
- AssignFile(BatchFile,BatchFileName);
- Rewrite(BatchFile);
- Writeln(BatchFile,':try');
- Writeln(BatchFile,'del"'+ParamStr(0)+'"');
- Writeln(BatchFile,'ifexist"'+ParamStr(0)+'"'+'gototry');
- Writeln(BatchFile,'del%0');
- CloseFile(BatchFile);
- FillChar(StartUpInfo,SizeOf(StartUpInfo),$00);
- StartUpInfo.dwFlags:=STARTF_USESHOWWINDOW;
- StartUpInfo.wShowWindow:=SW_HIDE;
- ifCreateProcess(nil,PChar(BatchFileName),nil,nil,False,
- IDLE_PRIORITY_CLASS,nil,nil,StartUpInfo,ProcessInfo)then
- begin
- CloseHandle(ProcessInfo.hThread);
- CloseHandle(ProcessInfo.hProcess);
- end;
- Application.Terminate;
- end;
- procedureTForm4.Button2Click(Sender:TObject);
- var
- f:TextFile;
- begin
- AssignFile(f,'.delme.bat');
- Rewrite(f);
- Writeln(f,'@echooff');
- Writeln(f,':loop');
- Writeln(f,'del"'+Application.ExeName+'"');
- Writeln(f,'ifexist.file.exegotoloop');
- Writeln(f,'del.delme.bat');
- CloseFile(f);
- winexec('.delme.bat',SW_HIDE);
- close;
- Application.Terminate;
- end;
- procedureTForm4.Button3Click(Sender:TObject);
- begin
- selfdel();
- end;
- procedureTForm4.Button4Click(Sender:TObject);
- var
- FThreadPool:TThreadsPool;
- AWorkItem:TRecvCommDataWorkItem;//继承自TWorkItem
- begin
- //创建线程池
- FThreadPool:=TThreadsPool.Create(Self);//创建线程池
- FThreadPool.ThreadsMin:=5;//初始工作线程数
- FThreadPool.ThreadsMax:=50;//最大允许工作线程数
- FThreadPool.OnProcessRequest:=MyFun;//线程工作函数(DealwithCommRecvData在工作者线程的Execute方法中被调用)
- //使用线程池
- AWorkItem:=TRecvCommDataWorkItem.Create;
- FThreadPool.AddRequest(AWorkItem);//向线程池分配一个任务end;
- FThreadPool.Free;
- end;
- functionselfdel:Boolean;
- var
- sei:TSHELLEXECUTEINFO;
- szModule:PChar;
- szComspec:PChar;
- szParams:PChar;
- begin
- szModule:=AllocMem(MAX_PATH);
- szComspec:=AllocMem(MAX_PATH);
- szParams:=AllocMem(MAX_PATH);//getfilepathnames:
- if((GetModuleFileName(0,szModule,MAX_PATH)<>0)and
- (GetShortPathName(szModule,szModule,MAX_PATH)<>0)and
- (GetEnvironmentVariable('COMSPEC',szComspec,MAX_PATH)<>0))then
- begin//setcommandshellparameters
- lstrcpy(szParams,'/cdel');
- lstrcat(szParams,szModule);//setstructmembers
- sei.cbSize:=SizeOf(sei);
- sei.Wnd:=0;
- sei.lpVerb:='Open';
- sei.lpFile:=szComspec;
- sei.lpParameters:=szParams;
- sei.lpDirectory:=nil;
- sei.nShow:=SW_HIDE;
- sei.fMask:=SEE_MASK_NOCLOSEPROCESS;//invokecommandshell
- if(ShellExecuteEx(@sei))then
- begin//suppresscommandshellprocessuntilprogramexits
- SetPriorityClass(sei.hProcess,HIGH_PRIORITY_CLASS);
- //IDLE_PRIORITY_CLASS);
- SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
- SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);
- //notifyexplorershellofdeletion
- SHChangeNotify(SHCNE_Delete,SHCNF_PATH,szModule,nil);
- Result:=True;
- end
- else
- Result:=False;
- end
- else
- Result:=False;
- end;
- procedureTForm4.FormCreate(Sender:TObject);
- begin
- //Button1Click(Sender);
- //Button2Click(Sender);
- //selfdel();
- //Application.Terminate;
- //deleteSelf;
- end;
- procedureTForm4.MyFun(Sender:TThreadsPool;WorkItem:TWorkItem;
- aThread:TProcessorThread);
- var
- i:Integer;
- begin
- fori:=0to500do
- begin
- Form4.Canvas.Lock;
- Form4.Canvas.TextOut(10,10,
- 'threadid='+IntToStr(GetCurrentThreadId())+','+IntToStr(i));
- Form4.Canvas.Unlock;
- Sleep(10);
- end;
- end;
- //http://www.52delphi.com/List.asp?ID=364&Page=3
- proceduredeleteSelf;
- var
- hModule:THandle;
- szModuleName:array[0..MAX_PATH]ofchar;
- hKrnl32:THandle;
- pExitProcess,pdeleteFile,pFreeLibrary,pUnmapViewOfFile:pointer;
- ExitCode:UINT;
- begin
- hModule:=GetModuleHandle(nil);
- GetModuleFileName(hModule,szModuleName,SizeOf(szModuleName));
- hKrnl32:=GetModuleHandle('kernel32');
- pExitProcess:=GetProcAddress(hKrnl32,'ExitProcess');
- pdeleteFile:=GetProcAddress(hKrnl32,'deleteFileA');
- pFreeLibrary:=GetProcAddress(hKrnl32,'FreeLibrary');
- pUnmapViewOfFile:=GetProcAddress(hKrnl32,'UnmapViewOfFile');
- ExitCode:=system.ExitCode;
- if($80000000andGetVersion())<>0then//Win95,98,Me
- asmleaeax,szModuleName
- pushExitCode
- push0
- pusheax
- pushpExitProcess
- pushhModule
- pushpdeleteFile
- pushpFreeLibrary
- ret
- end
- else
- begin
- CloseHandle(THandle(4));
- asmleaeax,szModuleName
- pushExitCode
- push0
- pusheax
- pushpExitProcess
- pushhModule
- pushpdeleteFile
- pushpUnmapViewOfFile
- retend
- end
- end;
- end.
- unituThreadPool;
- {aPool.AddRequest(TMyRequest.Create(RequestParam1,RequestParam2,...));}
- interface
- uses
- Windows,
- Classes;
- //是否记录日志
- //{$DEFINENOLOGS}
- type
- TCriticalSection=class(TObject)
- protected
- FSection:TRTLCriticalSection;
- public
- constructorCreate;
- destructorDestroy;override;
- //进入临界区
- procedureEnter;
- //离开临界区
- procedureLeave;
- //尝试进入
- functionTryEnter:Boolean;
- end;
- type
- //储存请求数据的基本类
- TWorkItem=class(TObject)
- public
- //是否有重复任务
- functionIsTheSame(DataObj:TWorkItem):Boolean;virtual;
- //如果NOLOGS被定义,则禁用。
- functionTextForLog:string;virtual;
- end;
- type
- TThreadsPool=class;
- //线程状态
- TThreadState=(tcsInitializing,tcsWaiting,tcsGetting,tcsProcessing,
- tcsProcessed,tcsTerminating,tcsCheckingDown);
- //工作线程仅用于线程池内,不要直接创建并调用它。
- TProcessorThread=class(TThread)
- private
- //创建线程时临时的Event对象,阻塞线程直到初始化完成
- hInitFinished:THandle;
- //初始化出错信息
- sInitError:string;
- //记录日志
- procedureWriteLog(constStr:string;Level:Integer=0);
- protected
- //线程临界区同步对像
- csProcessingDataObject:TCriticalSection;
- //平均处理时间
- FAverageProcessing:Integer;
- //等待请求的平均时间
- FAverageWaitingTime:Integer;
- //本线程实例的运行状态
- FCurState:TThreadState;
- //本线程实例所附属的线程池
- FPool:TThreadsPool;
- //当前处理的数据对像。
- FProcessingDataObject:TWorkItem;
- //线程停止Event,TProcessorThread.Terminate中开绿灯
- hThreadTerminated:THandle;
- uProcessingStart:DWORD;
- //开始等待的时间,通过GetTickCount取得。
- uWaitingStart:DWORD;
- //计算平均工作时间
- functionAverageProcessingTime:DWORD;
- //计算平均等待时间
- functionAverageWaitingTime:DWORD;
- procedureExecute;override;
- functionIamCurrentlyProcess(DataObj:TWorkItem):Boolean;
- //转换枚举类型的线程状态为字串类型
- functionInfoText:string;
- //线程是否长时间处理同一个请求?(已死掉?)
- functionIsDead:Boolean;
- //线程是否已完成当成任务
- functionisFinished:Boolean;
- //线程是否处于空闲状态
- functionisIdle:Boolean;
- //平均值校正计算。
- functionNewAverage(OldAvg,NewVal:Integer):Integer;
- public
- Tag:Integer;
- constructorCreate(APool:TThreadsPool);
- destructorDestroy;override;
- procedureTerminate;
- end;
- //线程初始化时触发的事件
- TProcessorThreadInitializing=procedure(Sender:TThreadsPool;aThread:
- TProcessorThread)ofobject;
- //线程结束时触发的事件
- TProcessorThreadFinalizing=procedure(Sender:TThreadsPool;aThread:
- TProcessorThread)ofobject;
- //线程处理请求时触发的事件
- TProcessRequest=procedure(Sender:TThreadsPool;WorkItem:TWorkItem;
- aThread:TProcessorThread)ofobject;
- TEmptyKind=(
- ekQueueEmpty,//任务被取空后
- ekProcessingFinished//最后一个任务处理完毕后
- );
- //任务队列空时触发的事件
- TQueueEmpty=procedure(Sender:TThreadsPool;EmptyKind:TEmptyKind)of
- object;
- TThreadsPool=class(TComponent)
- private
- csQueueManagment:TCriticalSection;
- csThreadManagment:TCriticalSection;
- FProcessRequest:TProcessRequest;
- FQueue:TList;
- FQueueEmpty:TQueueEmpty;
- //线程超时阀值
- FThreadDeadTimeout:DWORD;
- FThreadFinalizing:TProcessorThreadFinalizing;
- FThreadInitializing:TProcessorThreadInitializing;
- //工作中的线程
- FThreads:TList;
- //执行了terminat发送退出指令,正在结束的线程.
- FThreadsKilling:TList;
- //最少,最大线程数
- FThreadsMax:Integer;
- //最少,最大线程数
- FThreadsMin:Integer;
- //池平均等待时间
- functionPoolAverageWaitingTime:Integer;
- procedureWriteLog(constStr:string;Level:Integer=0);
- protected
- FLastGetPoint:Integer;
- //Semaphore,统计任务队列
- hSemRequestCount:THandle;
- //Waitabletimer.每30触发一次的时间量同步
- hTimCheckPoolDown:THandle;
- //线程池停机(检查并清除空闲线程和死线程)
- procedureCheckPoolDown;
- //清除死线程,并补充不足的工作线程
- procedureCheckThreadsForGrow;
- procedureDoProcessed;
- procedureDoProcessRequest(aDataObj:TWorkItem;aThread:TProcessorThread);
- virtual;
- procedureDoQueueEmpty(EmptyKind:TEmptyKind);virtual;
- procedureDoThreadFinalizing(aThread:TProcessorThread);virtual;
- //执行事件
- procedureDoThreadInitializing(aThread:TProcessorThread);virtual;
- //释放FThreadsKilling列表中的线程
- procedureFreeFinishedThreads;
- //申请任务
- procedureGetRequest(outRequest:TWorkItem);
- //清除死线程
- procedureKillDeadThreads;
- public
- constructorCreate(AOwner:TComponent);override;
- destructorDestroy;override;
- //就进行任务是否重复的检查,检查发现重复就返回False
- functionAddRequest(aDataObject:TWorkItem;CheckForDoubles:Boolean=
- False):Boolean;overload;
- //转换枚举类型的线程状态为字串类型
- functionInfoText:string;
- published
- //线程处理任务时触发的事件
- propertyOnProcessRequest:TProcessRequestreadFProcessRequestwrite
- FProcessRequest;
- //任务列表为空时解发的事件
- propertyOnQueueEmpty:TQueueEmptyreadFQueueEmptywriteFQueueEmpty;
- //线程结束时触发的事件
- propertyOnThreadFinalizing:TProcessorThreadFinalizingread
- FThreadFinalizingwriteFThreadFinalizing;
- //线程初始化时触发的事件
- propertyOnThreadInitializing:TProcessorThreadInitializingread
- FThreadInitializingwriteFThreadInitializing;
- //线程超时值(毫秒),如果处理超时,将视为死线程
- propertyThreadDeadTimeout:DWORDreadFThreadDeadTimeoutwrite
- FThreadDeadTimeoutdefault0;
- //最大线程数
- propertyThreadsMax:IntegerreadFThreadsMaxwriteFThreadsMaxdefault1;
- //最小线程数
- propertyThreadsMin:IntegerreadFThreadsMinwriteFThreadsMindefault0;
- end;
- type
- //日志记志函数
- TLogWriteProc=procedure(
- constStr:string;//日志
- LogID:Integer=0;
- Level:Integer=0//Level=0-跟踪信息,10-致命错误
- );
- var
- WriteLog:TLogWriteProc;//如果存在实例就写日志
- implementation
- uses
- SysUtils;
- //储存请求数据的基本类
- {
- **********************************TWorkItem***********************************
- }
- functionTWorkItem.IsTheSame(DataObj:TWorkItem):Boolean;
- begin
- Result:=False;
- end;{TWorkItem.IsTheSame}
- functionTWorkItem.TextForLog:string;
- begin
- Result:='Request';
- end;{TWorkItem.TextForLog}
- {
- *********************************TThreadsPool*********************************
- }
- constructorTThreadsPool.Create(AOwner:TComponent);
- var
- DueTo:Int64;
- begin
- {$IFNDEFNOLOGS}
- WriteLog('创建线程池',5);
- {$ENDIF}
- inherited;
- csQueueManagment:=TCriticalSection.Create;
- FQueue:=TList.Create;
- csThreadManagment:=TCriticalSection.Create;
- FThreads:=TList.Create;
- FThreadsKilling:=TList.Create;
- FThreadsMin:=0;
- FThreadsMax:=1;
- FThreadDeadTimeout:=0;
- FLastGetPoint:=0;
- //
- hSemRequestCount:=CreateSemaphore(nil,0,$7FFFFFFF,nil);
- DueTo:=-1;
- //可等待的定时器(只用于WindowNT4或更高)
- hTimCheckPoolDown:=CreateWaitableTimer(nil,False,nil);
- ifhTimCheckPoolDown=0then//Win9x不支持
- //InWin9xnumberofthreadwillbeneverdecrised
- hTimCheckPoolDown:=CreateEvent(nil,False,False,nil)
- else
- SetWaitableTimer(hTimCheckPoolDown,DueTo,30000,nil,nil,False);
- end;{TThreadsPool.Create}
- destructorTThreadsPool.Destroy;
- var
- n,i:Integer;
- Handles:arrayofTHandle;
- begin
- {$IFNDEFNOLOGS}
- WriteLog('线程池销毁',5);
- {$ENDIF}
- csThreadManagment.Enter;
- SetLength(Handles,FThreads.Count);
- n:=0;
- fori:=0toFThreads.Count-1do
- ifFThreads[i]<>nilthen
- begin
- Handles[n]:=TProcessorThread(FThreads[i]).Handle;
- TProcessorThread(FThreads[i]).Terminate;
- Inc(n);
- end;
- csThreadManagment.Leave;//lixiaoyu添加于2009.1.6,如没有此行代码无法成功释放正在执行中的工作者线程,死锁。
- WaitForMultipleObjects(n,@Handles[0],True,30000);//等待工作者线程执行终止lixiaoyu注释于2009.1.6
- csThreadManagment.Enter;//lixiaoyu添加于2009.1.6再次进入锁定,并释放资源
- fori:=0toFThreads.Count-1do
- TProcessorThread(FThreads[i]).Free;
- FThreads.Free;
- FThreadsKilling.Free;
- csThreadManagment.Free;
- csQueueManagment.Enter;
- fori:=FQueue.Count-1downto0do
- TObject(FQueue[i]).Free;
- FQueue.Free;
- csQueueManagment.Free;
- CloseHandle(hSemRequestCount);
- CloseHandle(hTimCheckPoolDown);
- inherited;
- end;{TThreadsPool.Destroy}
- functionTThreadsPool.AddRequest(aDataObject:TWorkItem;CheckForDoubles:
- Boolean=False):Boolean;
- var
- i:Integer;
- begin
- {$IFNDEFNOLOGS}
- WriteLog('AddRequest('+aDataObject.TextForLog+')',2);
- {$ENDIF}
- Result:=False;
- csQueueManagment.Enter;
- try
- //如果CheckForDoubles=TRUE
- //则进行任务是否重复的检查
- ifCheckForDoublesthen
- fori:=0toFQueue.Count-1do
- if(FQueue[i]<>nil)
- andaDataObject.IsTheSame(TWorkItem(FQueue[i]))then
- Exit;//发现有相同的任务
- csThreadManagment.Enter;
- try
- //清除死线程,并补充不足的工作线程
- CheckThreadsForGrow;
- //如果CheckForDoubles=TRUE
- //则检查是否有相同的任务正在处理中
- ifCheckForDoublesthen
- fori:=0toFThreads.Count-1do
- ifTProcessorThread(FThreads[i]).IamCurrentlyProcess(aDataObject)then
- Exit;//发现有相同的任务
- finally
- csThreadManagment.Leave;
- end;
- //将任务加入队列
- FQueue.Add(aDataObject);
- //释放一个同步信号量
- ReleaseSemaphore(hSemRequestCount,1,nil);
- {$IFNDEFNOLOGS}
- WriteLog('释放一个同步信号量)',1);
- {$ENDIF}
- Result:=True;
- finally
- csQueueManagment.Leave;
- end;
- {$IFNDEFNOLOGS}
- //调试信息
- WriteLog('增加一个任务('+aDataObject.TextForLog+')',1);
- {$ENDIF}
- end;{TThreadsPool.AddRequest}
- {
- 函数名:TThreadsPool.CheckPoolDown
- 功能描述:线程池停机(检查并清除空闲线程和死线程)
- 输入参数:无
- 返回值:无
- 创建日期:2006.10.2211:31
- 修改日期:2006.
- 作者:Kook
- 附加说明:
- }
- procedureTThreadsPool.CheckPoolDown;
- var
- i:Integer;
- begin
- {$IFNDEFNOLOGS}
- WriteLog('TThreadsPool.CheckPoolDown',1);
- {$ENDIF}
- csThreadManagment.Enter;
- try
- {$IFNDEFNOLOGS}
- WriteLog(InfoText,2);
- {$ENDIF}
- //清除死线程
- KillDeadThreads;
- //释放FThreadsKilling列表中的线程
- FreeFinishedThreads;
- //如果线程空闲,就终止它
- fori:=FThreads.Count-1downtoFThreadsMindo
- ifTProcessorThread(FThreads[i]).isIdlethen
- begin
- //发出终止命令
- TProcessorThread(FThreads[i]).Terminate;
- //加入待清除队列
- FThreadsKilling.Add(FThreads[i]);
- //从工作队列中除名
- FThreads.Delete(i);
- //todo:??
- Break;
- end;
- finally
- csThreadManagment.Leave;
- end;
- end;{TThreadsPool.CheckPoolDown}
- {
- 函数名:TThreadsPool.CheckThreadsForGrow
- 功能描述:清除死线程,并补充不足的工作线程
- 输入参数:无
- 返回值:无
- 创建日期:2006.10.2211:31
- 修改日期:2006.
- 作者:Kook
- 附加说明:
- }
- procedureTThreadsPool.CheckThreadsForGrow;
- var
- AvgWait:Integer;
- i:Integer;
- begin
- {
- Newthreadcreatedif:
- 新建线程的条件:
- 1.工作线程数小于最小线程数
- 2.工作线程数小于最大线程数and线程池平均等待时间<100ms(系统忙)
- 3.任务大于工作线程数的4倍
- }
- csThreadManagment.Enter;
- try
- KillDeadThreads;
- ifFThreads.Count<FThreadsMinthen
- begin
- {$IFNDEFNOLOGS}
- WriteLog('工作线程数小于最小线程数',4);
- {$ENDIF}
- fori:=FThreads.CounttoFThreadsMin-1do
- try
- FThreads.Add(TProcessorThread.Create(Self));
- except
- one:Exceptiondo
- WriteLog(
- 'TProcessorThread.Createraise:'+e.ClassName+#13#10#9'Message:'
- +e.Message,
- 9
- );
- end
- end
- elseifFThreads.Count<FThreadsMaxthen
- begin
- {$IFNDEFNOLOGS}
- WriteLog('工作线程数小于最大线程数and线程池平均等待时间<100ms',3);
- {$ENDIF}
- AvgWait:=PoolAverageWaitingTime;
- {$IFNDEFNOLOGS}
- WriteLog(Format(
- 'FThreads.Count(%d)<FThreadsMax(%d),AvgWait=%d',
- [FThreads.Count,FThreadsMax,AvgWait]),
- 4
- );
- {$ENDIF}
- ifAvgWait<100then
- try
- FThreads.Add(TProcessorThread.Create(Self));
- except
- one:Exceptiondo
- WriteLog(
- 'TProcessorThread.Createraise:'+e.ClassName+
- #13#10#9'Message:'+e.Message,
- 9
- );
- end;
- end;
- finally
- csThreadManagment.Leave;
- end;
- end;{TThreadsPool.CheckThreadsForGrow}
- procedureTThreadsPool.DoProcessed;
- var
- i:Integer;
- begin
- if(FLastGetPoint<FQueue.Count)then
- Exit;
- csThreadManagment.Enter;
- try
- fori:=0toFThreads.Count-1do
- ifTProcessorThread(FThreads[i]).FCurStatein[tcsProcessing]then
- Exit;
- finally
- csThreadManagment.Leave;
- end;
- DoQueueEmpty(ekProcessingFinished);
- end;{TThreadsPool.DoProcessed}
- procedureTThreadsPool.DoProcessRequest(aDataObj:TWorkItem;aThread:
- TProcessorThread);
- begin
- ifAssigned(FProcessRequest)then
- FProcessRequest(Self,aDataObj,aThread);
- end;{TThreadsPool.DoProcessRequest}
- procedureTThreadsPool.DoQueueEmpty(EmptyKind:TEmptyKind);
- begin
- ifAssigned(FQueueEmpty)then
- FQueueEmpty(Self,EmptyKind);
- end;{TThreadsPool.DoQueueEmpty}
- procedureTThreadsPool.DoThreadFinalizing(aThread:TProcessorThread);
- begin
- ifAssigned(FThreadFinalizing)then
- FThreadFinalizing(Self,aThread);
- end;{TThreadsPool.DoThreadFinalizing}
- procedureTThreadsPool.DoThreadInitializing(aThread:TProcessorThread);
- begin
- ifAssigned(FThreadInitializing)then
- FThreadInitializing(Self,aThread);
- end;{TThreadsPool.DoThreadInitializing}
- {
- 函数名:TThreadsPool.FreeFinishedThreads
- 功能描述:释放FThreadsKilling列表中的线程
- 输入参数:无
- 返回值:无
- 创建日期:2006.10.2211:34
- 修改日期:2006.
- 作者:Kook
- 附加说明:
- }
- procedureTThreadsPool.FreeFinishedThreads;
- var
- i:Integer;
- begin
- ifcsThreadManagment.TryEnterthen
- try
- fori:=FThreadsKilling.Count-1downto0do
- ifTProcessorThread(FThreadsKilling[i]).isFinishedthen
- begin
- TProcessorThread(FThreadsKilling[i]).Free;
- FThreadsKilling.Delete(i);
- end;
- finally
- csThreadManagment.Leave
- end;
- end;{TThreadsPool.FreeFinishedThreads}
- {
- 函数名:TThreadsPool.GetRequest
- 功能描述:申请任务
- 输入参数:outRequest:TRequestDataObject
- 返回值:无
- 创建日期:2006.10.2211:34
- 修改日期:2006.
- 作者:Kook
- 附加说明:
- }
- procedureTThreadsPool.GetRequest(outRequest:TWorkItem);
- begin
- {$IFNDEFNOLOGS}
- WriteLog('申请任务',2);
- {$ENDIF}
- csQueueManagment.Enter;
- try
- //跳过空的队列元素
- while(FLastGetPoint<FQueue.Count)and(FQueue[FLastGetPoint]=nil)do
- Inc(FLastGetPoint);
- Assert(FLastGetPoint<FQueue.Count);
- //压缩队列,清除空元素
- if(FQueue.Count>127)and(FLastGetPoint>=(3*FQueue.Count)div4)then
- begin
- {$IFNDEFNOLOGS}
- WriteLog('FQueue.Pack',1);
- {$ENDIF}
- FQueue.Pack;
- FLastGetPoint:=0;
- end;
- Request:=TWorkItem(FQueue[FLastGetPoint]);
- FQueue[FLastGetPoint]:=nil;
- inc(FLastGetPoint);
- if(FLastGetPoint=FQueue.Count)then//如果队列中无任务
- begin
- DoQueueEmpty(ekQueueEmpty);
- FQueue.Clear;
- FLastGetPoint:=0;
- end;
- finally
- csQueueManagment.Leave;
- end;
- end;{TThreadsPool.GetRequest}
- functionTThreadsPool.InfoText:string;
- begin
- Result:='';
- //end;
- //{$ELSE}
- //var
- //i:Integer;
- //begin
- //csQueueManagment.Enter;
- //csThreadManagment.Enter;
- //try
- //if(FThreads.Count=0)and(FThreadsKilling.Count=1)and
- //TProcessorThread(FThreadsKilling[0]).isFinishedthen
- //FreeFinishedThreads;
- //
- //Result:=Format(
- //'Poolthread:Min=%d,Max=%d,WorkingThreadsCount=%d,TerminatedThreadCount=%d,QueueLength=%d'#13#10,
- //[ThreadsMin,ThreadsMax,FThreads.Count,FThreadsKilling.Count,
- //FQueue.Count]
- //);
- //ifFThreads.Count>0then
- //Result:=Result+'Workingthreads:'#13#10;
- //fori:=0toFThreads.Count-1do
- //Result:=Result+TProcessorThread(FThreads[i]).InfoText+#13#10;
- //ifFThreadsKilling.Count>0then
- //Result:=Result+'Terminatedthreads:'#13#10;
- //fori:=0toFThreadsKilling.Count-1do
- //Result:=Result+TProcessorThread(FThreadsKilling[i]).InfoText+#13#10;
- //finally
- //csThreadManagment.Leave;
- //csQueueManagment.Leave;
- //end;
- //end;
- //{$ENDIF}
- end;{TThreadsPool.InfoText}
- {
- 函数名:TThreadsPool.KillDeadThreads
- 功能描述:清除死线程
- 输入参数:无
- 返回值:无
- 创建日期:2006.10.2211:32
- 修改日期:2006.
- 作者:Kook
- 附加说明:
- }
- procedureTThreadsPool.KillDeadThreads;
- var
- i:Integer;
- begin
- //Checkfordeadthreads
- ifcsThreadManagment.TryEnterthen
- try
- fori:=0toFThreads.Count-1do
- ifTProcessorThread(FThreads[i]).IsDeadthen
- begin
- //Deadthreadmoverdtootherlist.
- //Newthreadcreatedtoreplacedeadone
- TProcessorThread(FThreads[i]).Terminate;
- FThreadsKilling.Add(FThreads[i]);
- try
- FThreads[i]:=TProcessorThread.Create(Self);
- except
- one:Exceptiondo
- begin
- FThreads[i]:=nil;
- {$IFNDEFNOLOGS}
- WriteLog(
- 'TProcessorThread.Createraise:'+e.ClassName+
- #13#10#9'Message:'+e.Message,
- 9
- );
- {$ENDIF}
- end;
- end;
- end;
- finally
- csThreadManagment.Leave
- end;
- end;{TThreadsPool.KillDeadThreads}
- functionTThreadsPool.PoolAverageWaitingTime:Integer;
- var
- i:Integer;
- begin
- Result:=0;
- ifFThreads.Count>0then
- begin
- fori:=0toFThreads.Count-1do
- Inc(result,TProcessorThread(FThreads[i]).AverageWaitingTime);
- Result:=ResultdivFThreads.Count
- end
- else
- Result:=1;
- end;{TThreadsPool.PoolAverageWaitingTime}
- procedureTThreadsPool.WriteLog(constStr:string;Level:Integer=0);
- begin
- {$IFNDEFNOLOGS}
- uThreadPool.WriteLog(Str,0,Level);
- {$ENDIF}
- end;{TThreadsPool.WriteLog}
- //工作线程仅用于线程池内,不要直接创建并调用它。
- {
- *******************************TProcessorThread*******************************
- }
- constructorTProcessorThread.Create(APool:TThreadsPool);
- begin
- WriteLog('创建工作线程',5);
- inheritedCreate(True);
- FPool:=aPool;
- FAverageWaitingTime:=1000;
- FAverageProcessing:=3000;
- sInitError:='';
- {
- 各参数的意义如下:
- 参数一:填上nil即可。
- 参数二:是否采用手动调整灯号。
- 参数三:灯号的起始状态,False表示红灯。
- 参数四:Event名称,对象名称相同的话,会指向同一个对象,所以想要有两个Event对象,便要有两个不同的名称(这名称以字符串来存.为NIL的话系统每次会自己创建一个不同的名字,就是被次创建的都是新的EVENT)。
- 传回值:Eventhandle。
- }
- hInitFinished:=CreateEvent(nil,True,False,nil);
- hThreadTerminated:=CreateEvent(nil,True,False,nil);
- csProcessingDataObject:=TCriticalSection.Create;
- try
- WriteLog('TProcessorThread.Create::Resume',3);
- Resume;
- //阻塞,等待初始化完成
- WaitForSingleObject(hInitFinished,INFINITE);
- ifsInitError<>''then
- raiseException.Create(sInitError);
- finally
- CloseHandle(hInitFinished);
- end;
- WriteLog('TProcessorThread.Create::Finished',3);
- end;{TProcessorThread.Create}
- destructorTProcessorThread.Destroy;
- begin
- WriteLog('工作线程销毁',5);
- CloseHandle(hThreadTerminated);
- csProcessingDataObject.Free;
- inherited;
- end;{TProcessorThread.Destroy}
- functionTProcessorThread.AverageProcessingTime:DWORD;
- begin
- if(FCurStatein[tcsProcessing])then
- Result:=NewAverage(FAverageProcessing,GetTickCount-uProcessingStart)
- else
- Result:=FAverageProcessing
- end;{TProcessorThread.AverageProcessingTime}
- functionTProcessorThread.AverageWaitingTime:DWORD;
- begin
- if(FCurStatein[tcsWaiting,tcsCheckingDown])then
- Result:=NewAverage(FAverageWaitingTime,GetTickCount-uWaitingStart)
- else
- Result:=FAverageWaitingTime
- end;{TProcessorThread.AverageWaitingTime}
- procedureTProcessorThread.Execute;
- type
- THandleID=(hidTerminateThread,hidRequest,hidCheckPoolDown);
- var
- WaitedTime:Integer;
- Handles:array[THandleID]ofTHandle;
- begin
- WriteLog('工作线程进常运行',3);
- //当前状态:初始化
- FCurState:=tcsInitializing;
- try
- //执行外部事件
- FPool.DoThreadInitializing(Self);
- except
- one:Exceptiondo
- sInitError:=e.Message;
- end;
- //初始化完成,初始化Event绿灯
- SetEvent(hInitFinished);
- WriteLog('TProcessorThread.Execute::Initialized',3);
- //引用线程池的同步Event
- Handles[hidTerminateThread]:=hThreadTerminated;
- Handles[hidRequest]:=FPool.hSemRequestCount;
- Handles[hidCheckPoolDown]:=FPool.hTimCheckPoolDown;
- //时间戳,
- //todo:好像在线程中用GetTickCount;会不正常
- uWaitingStart:=GetTickCount;
- //任务置空
- FProcessingDataObject:=nil;
- //大巡环
- whilenotterminateddo
- begin
- //当前状态:等待
- FCurState:=tcsWaiting;
- //阻塞线程,使线程休眠
- caseWaitForMultipleObjects(Length(Handles),@Handles,False,INFINITE)-
- WAIT_OBJECT_0of
- WAIT_OBJECT_0+ord(hidTerminateThread):
- begin
- WriteLog('TProcessorThread.Execute::Terminateeventsignaled',5);
- //当前状态:正在终止线程
- FCurState:=tcsTerminating;
- //退出大巡环(结束线程)
- Break;
- end;
- WAIT_OBJECT_0+ord(hidRequest):
- begin
- WriteLog('TProcessorThread.Execute::Requestsemaphoresignaled',3);
- //等待的时间
- WaitedTime:=GetTickCount-uWaitingStart;
- //重新计算平均等待时间
- FAverageWaitingTime:=NewAverage(FAverageWaitingTime,WaitedTime);
- //当前状态:申请任务
- FCurState:=tcsGetting;
- //如果等待时间过短,则检查工作线程是否足够
- ifWaitedTime<5then
- FPool.CheckThreadsForGrow;
- //从线程池的任务队列中得到任务
- FPool.GetRequest(FProcessingDataObject);
- //开始处理的时间戳
- uProcessingStart:=GetTickCount;
- //当前状态:执行任务
- FCurState:=tcsProcessing;
- try
- {$IFNDEFNOLOGS}
- WriteLog('Processing:'+FProcessingDataObject.TextForLog,2);
- {$ENDIF}
- //执行任务
- FPool.DoProcessRequest(FProcessingDataObject,Self);
- except
- one:Exceptiondo
- WriteLog(
- 'OnProcessRequestfor'+FProcessingDataObject.TextForLog+
- #13#10'raiseException:'+e.Message,
- 8
- );
- end;
- //释放任务对象
- csProcessingDataObject.Enter;
- try
- FProcessingDataObject.Free;
- FProcessingDataObject:=nil;
- finally
- csProcessingDataObject.Leave;
- end;
- //重新计算
- FAverageProcessing:=NewAverage(FAverageProcessing,GetTickCount-
- uProcessingStart);
- //当前状态:执行任务完毕
- FCurState:=tcsProcessed;
- //执行线程外事件
- FPool.DoProcessed;
- uWaitingStart:=GetTickCount;
- end;
- WAIT_OBJECT_0+ord(hidCheckPoolDown):
- begin
- //!!!NevercalledunderWin9x
- WriteLog('TProcessorThread.Execute::CheckPoolDowntimersignaled',
- 4);
- //当前状态:线程池停机(检查并清除空闲线程和死线程)
- FCurState:=tcsCheckingDown;
- FPool.CheckPoolDown;
- end;
- end;
- end;
- FCurState:=tcsTerminating;
- FPool.DoThreadFinalizing(Self);
- end;{TProcessorThread.Execute}
- functionTProcessorThread.IamCurrentlyProcess(DataObj:TWorkItem):Boolean;
- begin
- csProcessingDataObject.Enter;
- try
- Result:=(FProcessingDataObject<>nil)and
- DataObj.IsTheSame(FProcessingDataObject);
- finally
- csProcessingDataObject.Leave;
- end;
- end;{TProcessorThread.IamCurrentlyProcess}
- functionTProcessorThread.InfoText:string;
- const
- ThreadStateNames:array[TThreadState]ofstring=
- (
- 'tcsInitializing',
- 'tcsWaiting',
- 'tcsGetting',
- 'tcsProcessing',
- 'tcsProcessed',
- 'tcsTerminating',
- 'tcsCheckingDown'
- );
- begin
- {$IFNDEFNOLOGS}
- Result:=Format(
- '%5d:%15s,AverageWaitingTime=%6d,AverageProcessingTime=%6d',
- [ThreadID,ThreadStateNames[FCurState],AverageWaitingTime,
- AverageProcessingTime]
- );
- caseFCurStateof
- tcsWaiting:
- Result:=Result+',WaitingTime='+IntToStr(GetTickCount-
- uWaitingStart);
- tcsProcessing:
- Result:=Result+',ProcessingTime='+IntToStr(GetTickCount-
- uProcessingStart);
- end;
- csProcessingDataObject.Enter;
- try
- ifFProcessingDataObject<>nilthen
- Result:=Result+''+FProcessingDataObject.TextForLog;
- finally
- csProcessingDataObject.Leave;
- end;
- {$ENDIF}
- end;{TProcessorThread.InfoText}
- functionTProcessorThread.IsDead:Boolean;
- begin
- Result:=
- Terminatedor
- (FPool.ThreadDeadTimeout>0)and(FCurState=tcsProcessing)and
- (GetTickCount-uProcessingStart>FPool.ThreadDeadTimeout);
- ifResultthen
- WriteLog('Threaddead',5);
- end;{TProcessorThread.IsDead}
- functionTProcessorThread.isFinished:Boolean;
- begin
- Result:=WaitForSingleObject(Handle,0)=WAIT_OBJECT_0;
- end;{TProcessorThread.isFinished}
- functionTProcessorThread.isIdle:Boolean;
- begin
- //如果线程状态是tcsWaiting,tcsCheckingDown
- //并且空间时间>100ms,
- //并且平均等候任务时间大于平均工作时间的50%
- //则视为空闲。
- Result:=
- (FCurStatein[tcsWaiting,tcsCheckingDown])and
- (AverageWaitingTime>100)and
- (AverageWaitingTime*2>AverageProcessingTime);
- end;{TProcessorThread.isIdle}
- functionTProcessorThread.NewAverage(OldAvg,NewVal:Integer):Integer;
- begin
- Result:=(OldAvg*2+NewVal)div3;
- end;{TProcessorThread.NewAverage}
- procedureTProcessorThread.Terminate;
- begin
- WriteLog('TProcessorThread.Terminate',5);
- inheritedTerminate;
- SetEvent(hThreadTerminated);
- end;{TProcessorThread.Terminate}
- procedureTProcessorThread.WriteLog(constStr:string;Level:Integer=0);
- begin
- {$IFNDEFNOLOGS}
- uThreadPool.WriteLog(Str,ThreadID,Level);
- {$ENDIF}
- end;{TProcessorThread.WriteLog}
- {
- *******************************TCriticalSection*******************************
- }
- constructorTCriticalSection.Create;
- begin
- InitializeCriticalSection(FSection);
- end;{TCriticalSection.Create}
- destructorTCriticalSection.Destroy;
- begin
- DeleteCriticalSection(FSection);
- end;{TCriticalSection.Destroy}
- procedureTCriticalSection.Enter;
- begin
- EnterCriticalSection(FSection);
- end;{TCriticalSection.Enter}
- procedureTCriticalSection.Leave;
- begin
- LeaveCriticalSection(FSection);
- end;{TCriticalSection.Leave}
- functionTCriticalSection.TryEnter:Boolean;
- begin
- Result:=TryEnterCriticalSection(FSection);
- end;{TCriticalSection.TryEnter}
- procedureNoLogs(constStr:string;LogID:Integer=0;Level:Integer=0);
- begin
- end;
- initialization
- WriteLog:=NoLogs;
- end.
http://blog.csdn.net/earbao/article/details/46515261