zoukankan      html  css  js  c++  java
  • delphi 自我删除和线程池(1000行代码,需要仔细研究)

    [delphi] view plain copy
     
    1. unit Unit4;  
    2.   
    3. interface  
    4.   
    5. uses  
    6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
    7.   Dialogs, StdCtrls, ShellAPI, ShlObj, uThreadPool;  
    8.   
    9. type  
    10.   TForm4 = class(TForm)  
    11.     Button1: TButton;  
    12.     Button2: TButton;  
    13.     Button3: TButton;  
    14.     Button4: TButton;  
    15.     procedure Button1Click(Sender: TObject);  
    16.     procedure FormCreate(Sender: TObject);  
    17.     procedure Button2Click(Sender: TObject);  
    18.     procedure Button3Click(Sender: TObject);  
    19.     procedure Button4Click(Sender: TObject);  
    20.   private  
    21.     { Private declarations }  
    22.   public  
    23.     { Public declarations }  
    24.     procedure MyFun(Sender: TThreadsPool; WorkItem: TWorkItem;  
    25.       aThread: TProcessorThread);  
    26.   end;  
    27.   TRecvCommDataWorkItem=class(TWorkItem)  
    28.   
    29.   end;  
    30.   
    31. function selfdel: Boolean;  
    32. procedure deleteSelf;  
    33.   
    34. var  
    35.   Form4: TForm4;  
    36.   
    37. implementation  
    38.   
    39. {$R *.dfm}  
    40.   
    41. procedure TForm4.Button1Click(Sender: TObject);  
    42.   
    43. var  
    44.   BatchFile: TextFile;  
    45.   BatchFileName: string;  
    46.   ProcessInfo: TProcessInformation;  
    47.   StartUpInfo: TStartupInfo;  
    48. begin  
    49.   BatchFileName := ExtractFilePath(ParamStr(0)) + '_deleteme.bat';  
    50.   AssignFile(BatchFile, BatchFileName);  
    51.   Rewrite(BatchFile);  
    52.   Writeln(BatchFile, ':try');  
    53.   Writeln(BatchFile, 'del "' + ParamStr(0) + '"');  
    54.   Writeln(BatchFile, 'if exist "' + ParamStr(0) + '"' + ' goto try');  
    55.   Writeln(BatchFile, 'del %0');  
    56.   CloseFile(BatchFile);  
    57.   FillChar(StartUpInfo, SizeOf(StartUpInfo), $00);  
    58.   StartUpInfo.dwFlags := STARTF_USESHOWWINDOW;  
    59.   StartUpInfo.wShowWindow := SW_HIDE;  
    60.   if CreateProcess(nil, PChar(BatchFileName), nil, nil, False,  
    61.     IDLE_PRIORITY_CLASS, nil, nil, StartUpInfo, ProcessInfo) then  
    62.   begin  
    63.     CloseHandle(ProcessInfo.hThread);  
    64.     CloseHandle(ProcessInfo.hProcess);  
    65.   end;  
    66.   Application.Terminate;  
    67. end;  
    68.   
    69. procedure TForm4.Button2Click(Sender: TObject);  
    70. var  
    71.   f: TextFile;  
    72. begin  
    73.   AssignFile(f, '.delme.bat');  
    74.   Rewrite(f);  
    75.   Writeln(f, '@echo off');  
    76.   Writeln(f, ':loop');  
    77.   Writeln(f, 'del "' + Application.ExeName + '"');  
    78.   Writeln(f, 'if exist .file.exe goto loop');  
    79.   Writeln(f, 'del .delme.bat');  
    80.   CloseFile(f);  
    81.   winexec('.delme.bat', SW_HIDE);  
    82.   close;  
    83.   Application.Terminate;  
    84. end;  
    85.   
    86. procedure TForm4.Button3Click(Sender: TObject);  
    87. begin  
    88.   selfdel();  
    89. end;  
    90.   
    91. procedure TForm4.Button4Click(Sender: TObject);  
    92. var  
    93.   FThreadPool: TThreadsPool;  
    94.   AWorkItem: TRecvCommDataWorkItem; // 继承自TWorkItem  
    95. begin  
    96.   // 创建线程池  
    97.   FThreadPool := TThreadsPool.Create(Self); // 创建线程池  
    98.   FThreadPool.ThreadsMin := 5; // 初始工作线程数  
    99.   FThreadPool.ThreadsMax := 50; // 最大允许工作线程数  
    100.   FThreadPool.OnProcessRequest := MyFun; // 线程工作函数(DealwithCommRecvData在工作者线程的Execute方法中被调用)  
    101.   
    102.   // 使用线程池  
    103.   AWorkItem := TRecvCommDataWorkItem.Create;  
    104.   
    105.   FThreadPool.AddRequest(AWorkItem); // 向线程池分配一个任务 end;  
    106.   
    107.   FThreadPool.Free;  
    108. end;  
    109.   
    110. function selfdel: Boolean;  
    111. var  
    112.   sei: TSHELLEXECUTEINFO;  
    113.   szModule: PChar;  
    114.   szComspec: PChar;  
    115.   szParams: PChar;  
    116. begin  
    117.   szModule := AllocMem(MAX_PATH);  
    118.   szComspec := AllocMem(MAX_PATH);  
    119.   szParams := AllocMem(MAX_PATH); // get file path names:  
    120.   if ((GetModuleFileName(0, szModule, MAX_PATH) <> 0) and  
    121.       (GetShortPathName(szModule, szModule, MAX_PATH) <> 0) and  
    122.       (GetEnvironmentVariable('COMSPEC', szComspec, MAX_PATH) <> 0)) then  
    123.   begin // set command shell parameters  
    124.     lstrcpy(szParams, '/c del ');  
    125.     lstrcat(szParams, szModule); // set struct members  
    126.     sei.cbSize := SizeOf(sei);  
    127.     sei.Wnd := 0;  
    128.     sei.lpVerb := 'Open';  
    129.     sei.lpFile := szComspec;  
    130.     sei.lpParameters := szParams;  
    131.     sei.lpDirectory := nil;  
    132.     sei.nShow := SW_HIDE;  
    133.     sei.fMask := SEE_MASK_NOCLOSEPROCESS; // invoke command shell  
    134.     if (ShellExecuteEx(@sei)) then  
    135.     begin // suppress command shell process until program exits  
    136.       SetPriorityClass(sei.hProcess, HIGH_PRIORITY_CLASS);  
    137.       // IDLE_PRIORITY_CLASS);  
    138.       SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);  
    139.       SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);  
    140.       // notify explorer shell of deletion  
    141.       SHChangeNotify(SHCNE_Delete, SHCNF_PATH, szModule, nil);  
    142.       Result := True;  
    143.     end  
    144.     else  
    145.       Result := False;  
    146.   end  
    147.   else  
    148.     Result := False;  
    149. end;  
    150.   
    151. procedure TForm4.FormCreate(Sender: TObject);  
    152. begin  
    153.   // Button1Click(Sender);  
    154.   // Button2Click(Sender);  
    155.   // selfdel();  
    156.   // Application.Terminate;  
    157.   // deleteSelf;  
    158. end;  
    159.   
    160. procedure TForm4.MyFun(Sender: TThreadsPool; WorkItem: TWorkItem;  
    161.   aThread: TProcessorThread);  
    162. var  
    163.   i: Integer;  
    164. begin  
    165.   for i := to 500 do  
    166.   begin  
    167.     Form4.Canvas.Lock;  
    168.     Form4.Canvas.TextOut(10, 10,  
    169.       'threadid=' + IntToStr(GetCurrentThreadId()) + ',' + IntToStr(i));  
    170.     Form4.Canvas.Unlock;  
    171.     Sleep(10);  
    172.   end;  
    173. end;  
    174.   
    175. // http://www.52delphi.com/List.asp?ID=364&Page=3  
    176. procedure deleteSelf;  
    177. var  
    178.   hModule: THandle;  
    179.   szModuleName: array [0 .. MAX_PATH] of char;  
    180.   hKrnl32: THandle;  
    181.   pExitProcess, pdeleteFile, pFreeLibrary, pUnmapViewOfFile: pointer;  
    182.   ExitCode: UINT;  
    183. begin  
    184.   hModule := GetModuleHandle(nil);  
    185.   GetModuleFileName(hModule, szModuleName, SizeOf(szModuleName));  
    186.   hKrnl32 := GetModuleHandle('kernel32');  
    187.   pExitProcess := GetProcAddress(hKrnl32, 'ExitProcess');  
    188.   pdeleteFile := GetProcAddress(hKrnl32, 'deleteFileA');  
    189.   pFreeLibrary := GetProcAddress(hKrnl32, 'FreeLibrary');  
    190.   pUnmapViewOfFile := GetProcAddress(hKrnl32, 'UnmapViewOfFile');  
    191.   ExitCode := system.ExitCode;  
    192.   if ($80000000 and GetVersion()) <> then // Win95, 98, Me  
    193.   asm lea eax, szModuleName  
    194.   push ExitCode  
    195.   push 0  
    196.   push eax  
    197.   push pExitProcess  
    198.   push hModule  
    199.   push pdeleteFile  
    200.   push pFreeLibrary  
    201.   ret  
    202.    end  
    203.   else  
    204.   begin  
    205.     CloseHandle(THandle(4));  
    206.       asm lea eax, szModuleName  
    207.       push ExitCode  
    208.       push 0  
    209.       push eax  
    210.       push pExitProcess  
    211.       push hModule  
    212.       push pdeleteFile  
    213.       push pUnmapViewOfFile  
    214.        ret end  
    215.   end  
    216. end;  
    217.   
    218. end.  
    [delphi] view plain copy
     
    1. unit uThreadPool;  
    2.   
    3. {   aPool.AddRequest(TMyRequest.Create(RequestParam1, RequestParam2, ...)); }  
    4.   
    5. interface  
    6. uses  
    7.   Windows,  
    8.   Classes;  
    9.   
    10. // 是否记录日志  
    11. // {$DEFINE NOLOGS}  
    12.   
    13. type  
    14.   TCriticalSection = class(TObject)  
    15.   protected  
    16.     FSection: TRTLCriticalSection;  
    17.   public  
    18.     constructor Create;  
    19.     destructor Destroy; override;  
    20.     // 进入临界区  
    21.     procedure Enter;  
    22.     // 离开临界区  
    23.     procedure Leave;  
    24.     // 尝试进入  
    25.     function TryEnter: Boolean;  
    26.   end;  
    27.   
    28. type  
    29.   // 储存请求数据的基本类  
    30.   TWorkItem = class(TObject)  
    31.   public  
    32.     // 是否有重复任务  
    33.     function IsTheSame(DataObj: TWorkItem): Boolean; virtual;  
    34.     // 如果 NOLOGS 被定义,则禁用。  
    35.     function TextForLog: string; virtual;  
    36.   end;  
    37.   
    38. type  
    39.   TThreadsPool = class;  
    40.   
    41.   //线程状态  
    42.   TThreadState = (tcsInitializing, tcsWaiting, tcsGetting, tcsProcessing,  
    43.     tcsProcessed, tcsTerminating, tcsCheckingDown);  
    44.   // 工作线程仅用于线程池内, 不要直接创建并调用它。  
    45.   TProcessorThread = class(TThread)  
    46.   private  
    47.     // 创建线程时临时的Event对象, 阻塞线程直到初始化完成  
    48.     hInitFinished: THandle;  
    49.     // 初始化出错信息  
    50.     sInitError: string;  
    51.     // 记录日志  
    52.     procedure WriteLog(const Str: string; Level: Integer = 0);  
    53.   protected  
    54.     // 线程临界区同步对像  
    55.     csProcessingDataObject: TCriticalSection;  
    56.     // 平均处理时间  
    57.     FAverageProcessing: Integer;  
    58.     // 等待请求的平均时间  
    59.     FAverageWaitingTime: Integer;  
    60.     // 本线程实例的运行状态  
    61.     FCurState: TThreadState;  
    62.     // 本线程实例所附属的线程池  
    63.     FPool: TThreadsPool;  
    64.     // 当前处理的数据对像。  
    65.     FProcessingDataObject: TWorkItem;  
    66.     // 线程停止 Event, TProcessorThread.Terminate 中开绿灯  
    67.     hThreadTerminated: THandle;  
    68.     uProcessingStart: DWORD;  
    69.     // 开始等待的时间, 通过 GetTickCount 取得。  
    70.     uWaitingStart: DWORD;  
    71.     // 计算平均工作时间  
    72.     function AverageProcessingTime: DWORD;  
    73.     // 计算平均等待时间  
    74.     function AverageWaitingTime: DWORD;  
    75.     procedure Execute; override;  
    76.     function IamCurrentlyProcess(DataObj: TWorkItem): Boolean;  
    77.     // 转换枚举类型的线程状态为字串类型  
    78.     function InfoText: string;  
    79.     // 线程是否长时间处理同一个请求?(已死掉?)  
    80.     function IsDead: Boolean;  
    81.     // 线程是否已完成当成任务  
    82.     function isFinished: Boolean;  
    83.     // 线程是否处于空闲状态  
    84.     function isIdle: Boolean;  
    85.     // 平均值校正计算。  
    86.     function NewAverage(OldAvg, NewVal: Integer): Integer;  
    87.   public  
    88.     Tag: Integer;  
    89.     constructor Create(APool: TThreadsPool);  
    90.     destructor Destroy; override;  
    91.     procedure Terminate;  
    92.   end;  
    93.   
    94.   // 线程初始化时触发的事件  
    95.   TProcessorThreadInitializing = procedure(Sender: TThreadsPool; aThread:  
    96.     TProcessorThread) of object;  
    97.   // 线程结束时触发的事件  
    98.   TProcessorThreadFinalizing = procedure(Sender: TThreadsPool; aThread:  
    99.     TProcessorThread) of object;  
    100.   // 线程处理请求时触发的事件  
    101.   TProcessRequest = procedure(Sender: TThreadsPool; WorkItem: TWorkItem;  
    102.     aThread: TProcessorThread) of object;  
    103.   TEmptyKind = (  
    104.     ekQueueEmpty, //任务被取空后  
    105.     ekProcessingFinished // 最后一个任务处理完毕后  
    106.     );  
    107.   // 任务队列空时触发的事件  
    108.   TQueueEmpty = procedure(Sender: TThreadsPool; EmptyKind: TEmptyKind) of  
    109.     object;  
    110.   
    111.   TThreadsPool = class(TComponent)  
    112.   private  
    113.     csQueueManagment: TCriticalSection;  
    114.     csThreadManagment: TCriticalSection;  
    115.     FProcessRequest: TProcessRequest;  
    116.     FQueue: TList;  
    117.     FQueueEmpty: TQueueEmpty;  
    118.     // 线程超时阀值  
    119.     FThreadDeadTimeout: DWORD;  
    120.     FThreadFinalizing: TProcessorThreadFinalizing;  
    121.     FThreadInitializing: TProcessorThreadInitializing;  
    122.     // 工作中的线程  
    123.     FThreads: TList;  
    124.     // 执行了 terminat 发送退出指令, 正在结束的线程.  
    125.     FThreadsKilling: TList;  
    126.     // 最少, 最大线程数  
    127.     FThreadsMax: Integer;  
    128.     // 最少, 最大线程数  
    129.     FThreadsMin: Integer;  
    130.     // 池平均等待时间  
    131.     function PoolAverageWaitingTime: Integer;  
    132.     procedure WriteLog(const Str: string; Level: Integer = 0);  
    133.   protected  
    134.     FLastGetPoint: Integer;  
    135.     // Semaphore, 统计任务队列  
    136.     hSemRequestCount: THandle;  
    137.     // Waitable timer. 每30触发一次的时间量同步  
    138.     hTimCheckPoolDown: THandle;  
    139.     // 线程池停机(检查并清除空闲线程和死线程)  
    140.     procedure CheckPoolDown;  
    141.     // 清除死线程,并补充不足的工作线程  
    142.     procedure CheckThreadsForGrow;  
    143.     procedure DoProcessed;  
    144.     procedure DoProcessRequest(aDataObj: TWorkItem; aThread: TProcessorThread);  
    145.       virtual;  
    146.     procedure DoQueueEmpty(EmptyKind: TEmptyKind); virtual;  
    147.     procedure DoThreadFinalizing(aThread: TProcessorThread); virtual;  
    148.     // 执行事件  
    149.     procedure DoThreadInitializing(aThread: TProcessorThread); virtual;  
    150.     // 释放 FThreadsKilling 列表中的线程  
    151.     procedure FreeFinishedThreads;  
    152.     // 申请任务  
    153.     procedure GetRequest(out Request: TWorkItem);  
    154.     // 清除死线程  
    155.     procedure KillDeadThreads;  
    156.   public  
    157.     constructor Create(AOwner: TComponent); override;  
    158.     destructor Destroy; override;  
    159.     // 就进行任务是否重复的检查, 检查发现重复就返回 False  
    160.     function AddRequest(aDataObject: TWorkItem; CheckForDoubles: Boolean =  
    161.       False): Boolean; overload;  
    162.     // 转换枚举类型的线程状态为字串类型  
    163.     function InfoText: string;  
    164.   published  
    165.     // 线程处理任务时触发的事件  
    166.     property OnProcessRequest: TProcessRequest read FProcessRequest write  
    167.       FProcessRequest;  
    168.     // 任务列表为空时解发的事件  
    169.     property OnQueueEmpty: TQueueEmpty read FQueueEmpty write FQueueEmpty;  
    170.     // 线程结束时触发的事件  
    171.     property OnThreadFinalizing: TProcessorThreadFinalizing read  
    172.       FThreadFinalizing write FThreadFinalizing;  
    173.     // 线程初始化时触发的事件  
    174.     property OnThreadInitializing: TProcessorThreadInitializing read  
    175.       FThreadInitializing write FThreadInitializing;  
    176.     // 线程超时值(毫秒), 如果处理超时,将视为死线程  
    177.     property ThreadDeadTimeout: DWORD read FThreadDeadTimeout write  
    178.       FThreadDeadTimeout default 0;  
    179.     // 最大线程数  
    180.     property ThreadsMax: Integer read FThreadsMax write FThreadsMax default 1;  
    181.     // 最小线程数  
    182.     property ThreadsMin: Integer read FThreadsMin write FThreadsMin default 0;  
    183.   end;  
    184.   
    185. type  
    186.   //日志记志函数  
    187.   TLogWriteProc = procedure(  
    188.     const Str: string; //日志  
    189.     LogID: Integer = 0;  
    190.     Level: Integer = //Level = 0 - 跟踪信息, 10 - 致命错误  
    191.     );  
    192.   
    193. var  
    194.   WriteLog: TLogWriteProc; // 如果存在实例就写日志  
    195.   
    196. implementation  
    197. uses  
    198.   SysUtils;  
    199.   
    200. // 储存请求数据的基本类  
    201. ********************************** TWorkItem *********************************** 
    202. }  
    203.   
    204. function TWorkItem.IsTheSame(DataObj: TWorkItem): Boolean;  
    205. begin  
    206.   Result := False;  
    207. end; { TWorkItem.IsTheSame }  
    208.   
    209. function TWorkItem.TextForLog: string;  
    210. begin  
    211.   Result := 'Request';  
    212. end; { TWorkItem.TextForLog }  
    213.   
    214. ********************************* TThreadsPool ********************************* 
    215. }  
    216.   
    217. constructor TThreadsPool.Create(AOwner: TComponent);  
    218. var  
    219.   DueTo: Int64;  
    220. begin  
    221. {$IFNDEF NOLOGS}  
    222.   WriteLog('创建线程池', 5);  
    223. {$ENDIF}  
    224.   inherited;  
    225.   csQueueManagment := TCriticalSection.Create;  
    226.   FQueue := TList.Create;  
    227.   csThreadManagment := TCriticalSection.Create;  
    228.   FThreads := TList.Create;  
    229.   FThreadsKilling := TList.Create;  
    230.   FThreadsMin := 0;  
    231.   FThreadsMax := 1;  
    232.   FThreadDeadTimeout := 0;  
    233.   FLastGetPoint := 0;  
    234.   //  
    235.   hSemRequestCount := CreateSemaphore(nil, 0, $7FFFFFFF, nil);  
    236.   
    237.   DueTo := -1;  
    238.   //可等待的定时器(只用于Window NT4或更高)  
    239.   hTimCheckPoolDown := CreateWaitableTimer(nil, False, nil);  
    240.   
    241.   if hTimCheckPoolDown = then // Win9x不支持  
    242.     // In Win9x number of thread will be never decrised  
    243.     hTimCheckPoolDown := CreateEvent(nil, False, False, nil)  
    244.   else  
    245.     SetWaitableTimer(hTimCheckPoolDown, DueTo, 30000, nil, nil, False);  
    246. end; { TThreadsPool.Create }  
    247.   
    248. destructor TThreadsPool.Destroy;  
    249. var  
    250.   n, i: Integer;  
    251.   Handles: array of THandle;  
    252. begin  
    253. {$IFNDEF NOLOGS}  
    254.   WriteLog('线程池销毁', 5);  
    255. {$ENDIF}  
    256.   csThreadManagment.Enter;  
    257.   
    258.   SetLength(Handles, FThreads.Count);  
    259.   n := 0;  
    260.   for i := to FThreads.Count - do  
    261.     if FThreads[i] <> nil then  
    262.     begin  
    263.       Handles[n] := TProcessorThread(FThreads[i]).Handle;  
    264.       TProcessorThread(FThreads[i]).Terminate;  
    265.       Inc(n);  
    266.     end;  
    267.   
    268.   csThreadManagment.Leave;  // lixiaoyu 添加于 2009.1.6,如没有此行代码无法成功释放正在执行中的工作者线程,死锁。  
    269.   
    270.   WaitForMultipleObjects(n, @Handles[0], True, 30000);  // 等待工作者线程执行终止  lixiaoyu 注释于 2009.1.6  
    271.   
    272.   csThreadManagment.Enter;  // lixiaoyu 添加于 2009.1.6 再次进入锁定,并释放资源  
    273.   for i := to FThreads.Count - do  
    274.     TProcessorThread(FThreads[i]).Free;  
    275.   FThreads.Free;  
    276.   FThreadsKilling.Free;  
    277.   csThreadManagment.Free;  
    278.   
    279.   csQueueManagment.Enter;  
    280.   for i := FQueue.Count - downto do  
    281.     TObject(FQueue[i]).Free;  
    282.   FQueue.Free;  
    283.   csQueueManagment.Free;  
    284.   
    285.   CloseHandle(hSemRequestCount);  
    286.   CloseHandle(hTimCheckPoolDown);  
    287.   inherited;  
    288. end; { TThreadsPool.Destroy }  
    289.   
    290. function TThreadsPool.AddRequest(aDataObject: TWorkItem; CheckForDoubles:  
    291.   Boolean = False): Boolean;  
    292. var  
    293.   i: Integer;  
    294. begin  
    295. {$IFNDEF NOLOGS}  
    296.   WriteLog('AddRequest(' + aDataObject.TextForLog + ')', 2);  
    297. {$ENDIF}  
    298.   Result := False;  
    299.   csQueueManagment.Enter;  
    300.   try  
    301.     // 如果 CheckForDoubles = TRUE  
    302.     // 则进行任务是否重复的检查  
    303.     if CheckForDoubles then  
    304.       for i := to FQueue.Count - do  
    305.         if (FQueue[i] <> nil)  
    306.           and aDataObject.IsTheSame(TWorkItem(FQueue[i])) then  
    307.           Exit; // 发现有相同的任务  
    308.   
    309.     csThreadManagment.Enter;  
    310.     try  
    311.       // 清除死线程,并补充不足的工作线程  
    312.       CheckThreadsForGrow;  
    313.   
    314.       // 如果 CheckForDoubles = TRUE  
    315.       // 则检查是否有相同的任务正在处理中  
    316.       if CheckForDoubles then  
    317.         for i := to FThreads.Count - do  
    318.           if TProcessorThread(FThreads[i]).IamCurrentlyProcess(aDataObject) then  
    319.             Exit; // 发现有相同的任务  
    320.   
    321.     finally  
    322.       csThreadManagment.Leave;  
    323.     end;  
    324.   
    325.     //将任务加入队列  
    326.     FQueue.Add(aDataObject);  
    327.   
    328.     //释放一个同步信号量  
    329.     ReleaseSemaphore(hSemRequestCount, 1, nil);  
    330. {$IFNDEF NOLOGS}  
    331.     WriteLog('释放一个同步信号量)', 1);  
    332. {$ENDIF}  
    333.     Result := True;  
    334.   finally  
    335.     csQueueManagment.Leave;  
    336.   end;  
    337. {$IFNDEF NOLOGS}  
    338.   //调试信息  
    339.   WriteLog('增加一个任务(' + aDataObject.TextForLog + ')', 1);  
    340. {$ENDIF}  
    341. end; { TThreadsPool.AddRequest }  
    342.   
    343. 函 数 名:TThreadsPool.CheckPoolDown 
    344. 功能描述:线程池停机(检查并清除空闲线程和死线程) 
    345. 输入参数:无 
    346. 返 回 值: 无 
    347. 创建日期:2006.10.22 11:31 
    348. 修改日期:2006. 
    349. 作    者:Kook 
    350. 附加说明: 
    351. }  
    352.   
    353. procedure TThreadsPool.CheckPoolDown;  
    354. var  
    355.   i: Integer;  
    356. begin  
    357. {$IFNDEF NOLOGS}  
    358.   WriteLog('TThreadsPool.CheckPoolDown', 1);  
    359. {$ENDIF}  
    360.   csThreadManagment.Enter;  
    361.   try  
    362. {$IFNDEF NOLOGS}  
    363.     WriteLog(InfoText, 2);  
    364. {$ENDIF}  
    365.     // 清除死线程  
    366.     KillDeadThreads;  
    367.     // 释放 FThreadsKilling 列表中的线程  
    368.     FreeFinishedThreads;  
    369.   
    370.     // 如果线程空闲,就终止它  
    371.     for i := FThreads.Count - downto FThreadsMin do  
    372.       if TProcessorThread(FThreads[i]).isIdle then  
    373.       begin  
    374.         //发出终止命令  
    375.         TProcessorThread(FThreads[i]).Terminate;  
    376.         //加入待清除队列  
    377.         FThreadsKilling.Add(FThreads[i]);  
    378.         //从工作队列中除名  
    379.         FThreads.Delete(i);  
    380.         //todo: ??  
    381.         Break;  
    382.       end;  
    383.   finally  
    384.     csThreadManagment.Leave;  
    385.   end;  
    386. end; { TThreadsPool.CheckPoolDown }  
    387.   
    388. 函 数 名:TThreadsPool.CheckThreadsForGrow 
    389. 功能描述:清除死线程,并补充不足的工作线程 
    390. 输入参数:无 
    391. 返 回 值: 无 
    392. 创建日期:2006.10.22 11:31 
    393. 修改日期:2006. 
    394. 作    者:Kook 
    395. 附加说明: 
    396. }  
    397.   
    398. procedure TThreadsPool.CheckThreadsForGrow;  
    399. var  
    400.   AvgWait: Integer;  
    401.   i: Integer;  
    402. begin  
    403.   
    404.     New thread created if: 
    405.     新建线程的条件: 
    406.       1. 工作线程数小于最小线程数 
    407.       2. 工作线程数小于最大线程数 and 线程池平均等待时间 < 100ms(系统忙) 
    408.       3. 任务大于工作线程数的4倍 
    409.   }  
    410.   
    411.   csThreadManagment.Enter;  
    412.   try  
    413.     KillDeadThreads;  
    414.     if FThreads.Count < FThreadsMin then  
    415.     begin  
    416. {$IFNDEF NOLOGS}  
    417.       WriteLog('工作线程数小于最小线程数', 4);  
    418. {$ENDIF}  
    419.       for i := FThreads.Count to FThreadsMin - do  
    420.       try  
    421.         FThreads.Add(TProcessorThread.Create(Self));  
    422.       except  
    423.         on e: Exception do  
    424.   
    425.           WriteLog(  
    426.             'TProcessorThread.Create raise: ' + e.ClassName + #13#10#9'Message: '  
    427.             + e.Message,  
    428.             9  
    429.             );  
    430.       end  
    431.     end  
    432.     else if FThreads.Count < FThreadsMax then  
    433.     begin  
    434. {$IFNDEF NOLOGS}  
    435.       WriteLog('工作线程数小于最大线程数 and 线程池平均等待时间 < 100ms', 3);  
    436. {$ENDIF}  
    437.       AvgWait := PoolAverageWaitingTime;  
    438. {$IFNDEF NOLOGS}  
    439.       WriteLog(Format(  
    440.         'FThreads.Count (%d)<FThreadsMax(%d), AvgWait=%d',  
    441.         [FThreads.Count, FThreadsMax, AvgWait]),  
    442.         4  
    443.         );  
    444. {$ENDIF}  
    445.   
    446.       if AvgWait < 100 then  
    447.       try  
    448.         FThreads.Add(TProcessorThread.Create(Self));  
    449.       except  
    450.         on e: Exception do  
    451.           WriteLog(  
    452.             'TProcessorThread.Create raise: ' + e.ClassName +  
    453.             #13#10#9'Message: ' + e.Message,  
    454.             9  
    455.             );  
    456.       end;  
    457.     end;  
    458.   finally  
    459.     csThreadManagment.Leave;  
    460.   end;  
    461. end; { TThreadsPool.CheckThreadsForGrow }  
    462.   
    463. procedure TThreadsPool.DoProcessed;  
    464. var  
    465.   i: Integer;  
    466. begin  
    467.   if (FLastGetPoint < FQueue.Count) then  
    468.     Exit;  
    469.   csThreadManagment.Enter;  
    470.   try  
    471.     for i := to FThreads.Count - do  
    472.       if TProcessorThread(FThreads[i]).FCurState in [tcsProcessing] then  
    473.         Exit;  
    474.   finally  
    475.     csThreadManagment.Leave;  
    476.   end;  
    477.   DoQueueEmpty(ekProcessingFinished);  
    478. end; { TThreadsPool.DoProcessed }  
    479.   
    480. procedure TThreadsPool.DoProcessRequest(aDataObj: TWorkItem; aThread:  
    481.   TProcessorThread);  
    482. begin  
    483.   if Assigned(FProcessRequest) then  
    484.     FProcessRequest(Self, aDataObj, aThread);  
    485. end; { TThreadsPool.DoProcessRequest }  
    486.   
    487. procedure TThreadsPool.DoQueueEmpty(EmptyKind: TEmptyKind);  
    488. begin  
    489.   if Assigned(FQueueEmpty) then  
    490.     FQueueEmpty(Self, EmptyKind);  
    491. end; { TThreadsPool.DoQueueEmpty }  
    492.   
    493. procedure TThreadsPool.DoThreadFinalizing(aThread: TProcessorThread);  
    494. begin  
    495.   if Assigned(FThreadFinalizing) then  
    496.     FThreadFinalizing(Self, aThread);  
    497. end; { TThreadsPool.DoThreadFinalizing }  
    498.   
    499. procedure TThreadsPool.DoThreadInitializing(aThread: TProcessorThread);  
    500. begin  
    501.   if Assigned(FThreadInitializing) then  
    502.     FThreadInitializing(Self, aThread);  
    503. end; { TThreadsPool.DoThreadInitializing }  
    504.   
    505. 函 数 名:TThreadsPool.FreeFinishedThreads 
    506. 功能描述:释放 FThreadsKilling 列表中的线程 
    507. 输入参数:无 
    508. 返 回 值: 无 
    509. 创建日期:2006.10.22 11:34 
    510. 修改日期:2006. 
    511. 作    者:Kook 
    512. 附加说明: 
    513. }  
    514.   
    515. procedure TThreadsPool.FreeFinishedThreads;  
    516. var  
    517.   i: Integer;  
    518. begin  
    519.   if csThreadManagment.TryEnter then  
    520.   try  
    521.     for i := FThreadsKilling.Count - downto do  
    522.       if TProcessorThread(FThreadsKilling[i]).isFinished then  
    523.       begin  
    524.         TProcessorThread(FThreadsKilling[i]).Free;  
    525.         FThreadsKilling.Delete(i);  
    526.       end;  
    527.   finally  
    528.     csThreadManagment.Leave  
    529.   end;  
    530. end; { TThreadsPool.FreeFinishedThreads }  
    531.   
    532. 函 数 名:TThreadsPool.GetRequest 
    533. 功能描述:申请任务 
    534. 输入参数:out Request: TRequestDataObject 
    535. 返 回 值: 无 
    536. 创建日期:2006.10.22 11:34 
    537. 修改日期:2006. 
    538. 作    者:Kook 
    539. 附加说明: 
    540. }  
    541.   
    542. procedure TThreadsPool.GetRequest(out Request: TWorkItem);  
    543. begin  
    544. {$IFNDEF NOLOGS}  
    545.   WriteLog('申请任务', 2);  
    546. {$ENDIF}  
    547.   csQueueManagment.Enter;  
    548.   try  
    549.     //跳过空的队列元素  
    550.     while (FLastGetPoint < FQueue.Count) and (FQueue[FLastGetPoint] = nil) do  
    551.       Inc(FLastGetPoint);  
    552.   
    553.     Assert(FLastGetPoint < FQueue.Count);  
    554.     //压缩队列,清除空元素  
    555.     if (FQueue.Count > 127) and (FLastGetPoint >= (3 * FQueue.Count) div 4) then  
    556.     begin  
    557. {$IFNDEF NOLOGS}  
    558.       WriteLog('FQueue.Pack', 1);  
    559. {$ENDIF}  
    560.       FQueue.Pack;  
    561.       FLastGetPoint := 0;  
    562.     end;  
    563.   
    564.     Request := TWorkItem(FQueue[FLastGetPoint]);  
    565.     FQueue[FLastGetPoint] := nil;  
    566.     inc(FLastGetPoint);  
    567.     if (FLastGetPoint = FQueue.Count) then //如果队列中无任务  
    568.     begin  
    569.   
    570.       DoQueueEmpty(ekQueueEmpty);  
    571.       FQueue.Clear;  
    572.       FLastGetPoint := 0;  
    573.     end;  
    574.   finally  
    575.     csQueueManagment.Leave;  
    576.   end;  
    577. end; { TThreadsPool.GetRequest }  
    578.   
    579. function TThreadsPool.InfoText: string;  
    580. begin  
    581.   Result := '';  
    582.   //end;  
    583.   //{$ELSE}  
    584.   //var  
    585.   //  i: Integer;  
    586.   //begin  
    587.   //  csQueueManagment.Enter;  
    588.   //  csThreadManagment.Enter;  
    589.   //  try  
    590.   //    if (FThreads.Count = 0) and (FThreadsKilling.Count = 1) and  
    591.   //      TProcessorThread(FThreadsKilling[0]).isFinished then  
    592.   //      FreeFinishedThreads;  
    593.   //  
    594.   //    Result := Format(  
    595.   //      'Pool thread: Min=%d, Max=%d, WorkingThreadsCount=%d, TerminatedThreadCount=%d, QueueLength=%d'#13#10,  
    596.   //      [ThreadsMin, ThreadsMax, FThreads.Count, FThreadsKilling.Count,  
    597.   //      FQueue.Count]  
    598.   //        );  
    599.   //    if FThreads.Count > 0 then  
    600.   //      Result := Result + 'Working threads:'#13#10;  
    601.   //    for i := 0 to FThreads.Count - 1 do  
    602.   //      Result := Result + TProcessorThread(FThreads[i]).InfoText + #13#10;  
    603.   //    if FThreadsKilling.Count > 0 then  
    604.   //      Result := Result + 'Terminated threads:'#13#10;  
    605.   //    for i := 0 to FThreadsKilling.Count - 1 do  
    606.   //      Result := Result + TProcessorThread(FThreadsKilling[i]).InfoText + #13#10;  
    607.   //  finally  
    608.   //    csThreadManagment.Leave;  
    609.   //    csQueueManagment.Leave;  
    610.   //  end;  
    611.   //end;  
    612.   //{$ENDIF}  
    613. end; { TThreadsPool.InfoText }  
    614.   
    615. 函 数 名:TThreadsPool.KillDeadThreads 
    616. 功能描述:清除死线程 
    617. 输入参数:无 
    618. 返 回 值: 无 
    619. 创建日期:2006.10.22 11:32 
    620. 修改日期:2006. 
    621. 作    者:Kook 
    622. 附加说明: 
    623. }  
    624.   
    625. procedure TThreadsPool.KillDeadThreads;  
    626. var  
    627.   i: Integer;  
    628. begin  
    629.   // Check for dead threads  
    630.   if csThreadManagment.TryEnter then  
    631.   try  
    632.     for i := to FThreads.Count - do  
    633.       if TProcessorThread(FThreads[i]).IsDead then  
    634.       begin  
    635.         // Dead thread moverd to other list.  
    636.         // New thread created to replace dead one  
    637.         TProcessorThread(FThreads[i]).Terminate;  
    638.         FThreadsKilling.Add(FThreads[i]);  
    639.         try  
    640.           FThreads[i] := TProcessorThread.Create(Self);  
    641.         except  
    642.           on e: Exception do  
    643.           begin  
    644.             FThreads[i] := nil;  
    645. {$IFNDEF NOLOGS}  
    646.             WriteLog(  
    647.               'TProcessorThread.Create raise: ' + e.ClassName +  
    648.               #13#10#9'Message: ' + e.Message,  
    649.               9  
    650.               );  
    651. {$ENDIF}  
    652.           end;  
    653.         end;  
    654.       end;  
    655.   finally  
    656.     csThreadManagment.Leave  
    657.   end;  
    658. end; { TThreadsPool.KillDeadThreads }  
    659.   
    660. function TThreadsPool.PoolAverageWaitingTime: Integer;  
    661. var  
    662.   i: Integer;  
    663. begin  
    664.   Result := 0;  
    665.   if FThreads.Count > then  
    666.   begin  
    667.     for i := to FThreads.Count - do  
    668.       Inc(result, TProcessorThread(FThreads[i]).AverageWaitingTime);  
    669.     Result := Result div FThreads.Count  
    670.   end  
    671.   else  
    672.     Result := 1;  
    673. end; { TThreadsPool.PoolAverageWaitingTime }  
    674.   
    675. procedure TThreadsPool.WriteLog(const Str: string; Level: Integer = 0);  
    676. begin  
    677. {$IFNDEF NOLOGS}  
    678.   uThreadPool.WriteLog(Str, 0, Level);  
    679. {$ENDIF}  
    680. end; { TThreadsPool.WriteLog }  
    681.   
    682. // 工作线程仅用于线程池内, 不要直接创建并调用它。  
    683. ******************************* TProcessorThread ******************************* 
    684. }  
    685.   
    686. constructor TProcessorThread.Create(APool: TThreadsPool);  
    687. begin  
    688.   WriteLog('创建工作线程', 5);  
    689.   inherited Create(True);  
    690.   FPool := aPool;  
    691.   
    692.   FAverageWaitingTime := 1000;  
    693.   FAverageProcessing := 3000;  
    694.   
    695.   sInitError := '';  
    696.   
    697.   各参数的意义如下: 
    698.     
    699.    参数一:填上 nil 即可。 
    700.    参数二:是否采用手动调整灯号。 
    701.    参数三:灯号的起始状态,False 表示红灯。 
    702.    参数四:Event 名称, 对象名称相同的话,会指向同一个对象,所以想要有两个Event对象,便要有两个不同的名称(这名称以字符串来存.为NIL的话系统每次会自己创建一个不同的名字,就是被次创建的都是新的EVENT)。 
    703.    传回值:Event handle。 
    704.   }  
    705.   hInitFinished := CreateEvent(nil, True, False, nil);  
    706.   hThreadTerminated := CreateEvent(nil, True, False, nil);  
    707.   csProcessingDataObject := TCriticalSection.Create;  
    708.   try  
    709.     WriteLog('TProcessorThread.Create::Resume', 3);  
    710.     Resume;  
    711.     //阻塞, 等待初始化完成  
    712.     WaitForSingleObject(hInitFinished, INFINITE);  
    713.     if sInitError <> '' then  
    714.       raise Exception.Create(sInitError);  
    715.   finally  
    716.     CloseHandle(hInitFinished);  
    717.   end;  
    718.   WriteLog('TProcessorThread.Create::Finished', 3);  
    719. end; { TProcessorThread.Create }  
    720.   
    721. destructor TProcessorThread.Destroy;  
    722. begin  
    723.   WriteLog('工作线程销毁', 5);  
    724.   CloseHandle(hThreadTerminated);  
    725.   csProcessingDataObject.Free;  
    726.   inherited;  
    727. end; { TProcessorThread.Destroy }  
    728.   
    729. function TProcessorThread.AverageProcessingTime: DWORD;  
    730. begin  
    731.   if (FCurState in [tcsProcessing]) then  
    732.     Result := NewAverage(FAverageProcessing, GetTickCount - uProcessingStart)  
    733.   else  
    734.     Result := FAverageProcessing  
    735. end; { TProcessorThread.AverageProcessingTime }  
    736.   
    737. function TProcessorThread.AverageWaitingTime: DWORD;  
    738. begin  
    739.   if (FCurState in [tcsWaiting, tcsCheckingDown]) then  
    740.     Result := NewAverage(FAverageWaitingTime, GetTickCount - uWaitingStart)  
    741.   else  
    742.     Result := FAverageWaitingTime  
    743. end; { TProcessorThread.AverageWaitingTime }  
    744.   
    745. procedure TProcessorThread.Execute;  
    746.   
    747. type  
    748.   THandleID = (hidTerminateThread, hidRequest, hidCheckPoolDown);  
    749. var  
    750.   WaitedTime: Integer;  
    751.   Handles: array[THandleID] of THandle;  
    752.   
    753. begin  
    754.   WriteLog('工作线程进常运行', 3);  
    755.   //当前状态:初始化  
    756.   FCurState := tcsInitializing;  
    757.   try  
    758.     //执行外部事件  
    759.     FPool.DoThreadInitializing(Self);  
    760.   except  
    761.     on e: Exception do  
    762.       sInitError := e.Message;  
    763.   end;  
    764.   
    765.   //初始化完成,初始化Event绿灯  
    766.   SetEvent(hInitFinished);  
    767.   
    768.   WriteLog('TProcessorThread.Execute::Initialized', 3);  
    769.   
    770.   //引用线程池的同步 Event  
    771.   Handles[hidTerminateThread] := hThreadTerminated;  
    772.   Handles[hidRequest] := FPool.hSemRequestCount;  
    773.   Handles[hidCheckPoolDown] := FPool.hTimCheckPoolDown;  
    774.   
    775.   //时间戳,  
    776.   //todo: 好像在线程中用 GetTickCount; 会不正常  
    777.   uWaitingStart := GetTickCount;  
    778.   //任务置空  
    779.   FProcessingDataObject := nil;  
    780.   
    781.   //大巡环  
    782.   while not terminated do  
    783.   begin  
    784.     //当前状态:等待  
    785.     FCurState := tcsWaiting;  
    786.     //阻塞线程,使线程休眠  
    787.     case WaitForMultipleObjects(Length(Handles), @Handles, False, INFINITE) -  
    788.       WAIT_OBJECT_0 of  
    789.   
    790.       WAIT_OBJECT_0 + ord(hidTerminateThread):  
    791.         begin  
    792.           WriteLog('TProcessorThread.Execute:: Terminate event signaled ', 5);  
    793.           //当前状态:正在终止线程  
    794.           FCurState := tcsTerminating;  
    795.           //退出大巡环(结束线程)  
    796.           Break;  
    797.         end;  
    798.   
    799.       WAIT_OBJECT_0 + ord(hidRequest):  
    800.         begin  
    801.           WriteLog('TProcessorThread.Execute:: Request semaphore signaled ', 3);  
    802.           //等待的时间  
    803.           WaitedTime := GetTickCount - uWaitingStart;  
    804.           //重新计算平均等待时间  
    805.           FAverageWaitingTime := NewAverage(FAverageWaitingTime, WaitedTime);  
    806.           //当前状态:申请任务  
    807.           FCurState := tcsGetting;  
    808.           //如果等待时间过短,则检查工作线程是否足够  
    809.           if WaitedTime < then  
    810.             FPool.CheckThreadsForGrow;  
    811.           //从线程池的任务队列中得到任务  
    812.           FPool.GetRequest(FProcessingDataObject);  
    813.           //开始处理的时间戳  
    814.           uProcessingStart := GetTickCount;  
    815.           //当前状态:执行任务  
    816.           FCurState := tcsProcessing;  
    817.           try  
    818. {$IFNDEF NOLOGS}  
    819.             WriteLog('Processing: ' + FProcessingDataObject.TextForLog, 2);  
    820. {$ENDIF}  
    821.             //执行任务  
    822.             FPool.DoProcessRequest(FProcessingDataObject, Self);  
    823.           except  
    824.             on e: Exception do  
    825.               WriteLog(  
    826.                 'OnProcessRequest for ' + FProcessingDataObject.TextForLog +  
    827.                 #13#10'raise Exception: ' + e.Message,  
    828.                 8  
    829.                 );  
    830.           end;  
    831.   
    832.           //释放任务对象  
    833.           csProcessingDataObject.Enter;  
    834.           try  
    835.             FProcessingDataObject.Free;  
    836.             FProcessingDataObject := nil;  
    837.           finally  
    838.             csProcessingDataObject.Leave;  
    839.           end;  
    840.           //重新计算  
    841.           FAverageProcessing := NewAverage(FAverageProcessing, GetTickCount -  
    842.             uProcessingStart);  
    843.           //当前状态:执行任务完毕  
    844.           FCurState := tcsProcessed;  
    845.           //执行线程外事件  
    846.           FPool.DoProcessed;  
    847.   
    848.           uWaitingStart := GetTickCount;  
    849.         end;  
    850.       WAIT_OBJECT_0 + ord(hidCheckPoolDown):  
    851.         begin  
    852.           // !!! Never called under Win9x  
    853.           WriteLog('TProcessorThread.Execute:: CheckPoolDown timer signaled ',  
    854.             4);  
    855.           //当前状态:线程池停机(检查并清除空闲线程和死线程)  
    856.           FCurState := tcsCheckingDown;  
    857.           FPool.CheckPoolDown;  
    858.         end;  
    859.     end;  
    860.   end;  
    861.   FCurState := tcsTerminating;  
    862.   
    863.   FPool.DoThreadFinalizing(Self);  
    864. end; { TProcessorThread.Execute }  
    865.   
    866. function TProcessorThread.IamCurrentlyProcess(DataObj: TWorkItem): Boolean;  
    867. begin  
    868.   csProcessingDataObject.Enter;  
    869.   try  
    870.     Result := (FProcessingDataObject <> nil) and  
    871.       DataObj.IsTheSame(FProcessingDataObject);  
    872.   finally  
    873.     csProcessingDataObject.Leave;  
    874.   end;  
    875. end; { TProcessorThread.IamCurrentlyProcess }  
    876.   
    877. function TProcessorThread.InfoText: string;  
    878.   
    879. const  
    880.   ThreadStateNames: array[TThreadState] of string =  
    881.   (  
    882.     'tcsInitializing',  
    883.     'tcsWaiting',  
    884.     'tcsGetting',  
    885.     'tcsProcessing',  
    886.     'tcsProcessed',  
    887.     'tcsTerminating',  
    888.     'tcsCheckingDown'  
    889.     );  
    890.   
    891. begin  
    892. {$IFNDEF NOLOGS}  
    893.   Result := Format(  
    894.     '%5d: %15s, AverageWaitingTime=%6d, AverageProcessingTime=%6d',  
    895.     [ThreadID, ThreadStateNames[FCurState], AverageWaitingTime,  
    896.     AverageProcessingTime]  
    897.       );  
    898.   case FCurState of  
    899.     tcsWaiting:  
    900.       Result := Result + ', WaitingTime=' + IntToStr(GetTickCount -  
    901.         uWaitingStart);  
    902.     tcsProcessing:  
    903.       Result := Result + ', ProcessingTime=' + IntToStr(GetTickCount -  
    904.         uProcessingStart);  
    905.   end;  
    906.   
    907.   csProcessingDataObject.Enter;  
    908.   try  
    909.     if FProcessingDataObject <> nil then  
    910.       Result := Result + ' ' + FProcessingDataObject.TextForLog;  
    911.   finally  
    912.     csProcessingDataObject.Leave;  
    913.   end;  
    914. {$ENDIF}  
    915. end; { TProcessorThread.InfoText }  
    916.   
    917. function TProcessorThread.IsDead: Boolean;  
    918. begin  
    919.   Result :=  
    920.     Terminated or  
    921.     (FPool.ThreadDeadTimeout > 0) and (FCurState = tcsProcessing) and  
    922.     (GetTickCount - uProcessingStart > FPool.ThreadDeadTimeout);  
    923.   if Result then  
    924.     WriteLog('Thread dead', 5);  
    925. end; { TProcessorThread.IsDead }  
    926.   
    927. function TProcessorThread.isFinished: Boolean;  
    928. begin  
    929.   Result := WaitForSingleObject(Handle, 0) = WAIT_OBJECT_0;  
    930. end; { TProcessorThread.isFinished }  
    931.   
    932. function TProcessorThread.isIdle: Boolean;  
    933. begin  
    934.   // 如果线程状态是 tcsWaiting, tcsCheckingDown  
    935.   // 并且 空间时间 > 100ms,  
    936.   // 并且 平均等候任务时间大于平均工作时间的 50%  
    937.   // 则视为空闲。  
    938.   Result :=  
    939.     (FCurState in [tcsWaiting, tcsCheckingDown]) and  
    940.     (AverageWaitingTime > 100) and  
    941.     (AverageWaitingTime * 2 > AverageProcessingTime);  
    942. end; { TProcessorThread.isIdle }  
    943.   
    944. function TProcessorThread.NewAverage(OldAvg, NewVal: Integer): Integer;  
    945. begin  
    946.   Result := (OldAvg * 2 + NewVal) div 3;  
    947. end; { TProcessorThread.NewAverage }  
    948.   
    949. procedure TProcessorThread.Terminate;  
    950. begin  
    951.   WriteLog('TProcessorThread.Terminate', 5);  
    952.   inherited Terminate;  
    953.   SetEvent(hThreadTerminated);  
    954. end; { TProcessorThread.Terminate }  
    955.   
    956. procedure TProcessorThread.WriteLog(const Str: string; Level: Integer = 0);  
    957. begin  
    958. {$IFNDEF NOLOGS}  
    959.   uThreadPool.WriteLog(Str, ThreadID, Level);  
    960. {$ENDIF}  
    961. end; { TProcessorThread.WriteLog }  
    962.   
    963. ******************************* TCriticalSection ******************************* 
    964. }  
    965.   
    966. constructor TCriticalSection.Create;  
    967. begin  
    968.   InitializeCriticalSection(FSection);  
    969. end; { TCriticalSection.Create }  
    970.   
    971. destructor TCriticalSection.Destroy;  
    972. begin  
    973.   DeleteCriticalSection(FSection);  
    974. end; { TCriticalSection.Destroy }  
    975.   
    976. procedure TCriticalSection.Enter;  
    977. begin  
    978.   EnterCriticalSection(FSection);  
    979. end; { TCriticalSection.Enter }  
    980.   
    981. procedure TCriticalSection.Leave;  
    982. begin  
    983.   LeaveCriticalSection(FSection);  
    984. end; { TCriticalSection.Leave }  
    985.   
    986. function TCriticalSection.TryEnter: Boolean;  
    987. begin  
    988.   Result := TryEnterCriticalSection(FSection);  
    989. end; { TCriticalSection.TryEnter }  
    990.   
    991. procedure NoLogs(const Str: string; LogID: Integer = 0; Level: Integer = 0);  
    992. begin  
    993. end;  
    994.   
    995. initialization  
    996.   WriteLog := NoLogs;  
    997. end.  

    http://blog.csdn.net/earbao/article/details/46515261

  • 相关阅读:
    java开发异常类型汇总
    dm642在线写EPROM.txt
    [Codecademy] HTML&CSS 第一课:HTML Basic
    bram和dram差别
    Advanced Fruits HDU杭电1503【LCS的保存】
    add Admob with Cocos2d-x on iOS
    一种基于Qt的可伸缩的全异步C/S架构server实现(五) 单层无中心集群
    【SSH2框架(理论篇)】--SSH2 Vs 经典三层
    CSS BFC学习笔记
    【智能家居篇】wifi网络结构(上)
  • 原文地址:https://www.cnblogs.com/findumars/p/5338851.html
Copyright © 2011-2022 走看看