• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

delphi自我删除和线程池(1000行代码,需要仔细研究)

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
[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;

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
安装linux版matlab的方法 - 苍生为念发布时间:2022-07-18
下一篇:
Ubantu16.04下创建matlab启动快捷键发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap