BusyQueue[i].Suspend;
BusyQueue[i].State := wtStop;
end;
hBusyLock.Leave;
hIDleLock.Enter;
for I := Low(IdleQueue) to High(IdleQueue) do
begin
IdleQueue[i].Suspend;
IdleQueue[i].State := wtStop;
end;
hIDleLock.Leave;
end;
function TThreadPool.QueueSize(const Queue: TWorkThreadQueue):Integer;
begin
Result := Length(Queue);
end;
//每次只留单线程进行空闲回收等待
procedure TThreadPool.RecoverIDle(Const wait:TWorkThread);
var
k:Integer;
begin
FAuto:=False;
//等待时间超时
FWaitFlag := False;
Waiting := wait;
hBusyLock.Enter;
RemoveFromQueue(BusyQueue,wait);
hBusyLock.Leave;
//补给一个空闲线程
CreateIdleThread();
WaitforSingleObject(hTimeJump,FRecoverInterval*ONEMINUTE);
//满足空闲时间到后并且空闲线程大于零,没有线程在执行任务,及任务队列为空
if (IdleQueueCount > 0)
and (BusyQueueCount = 0) //正在等待的是清空空闲线程
and (TaskQueueCount = 0) then
begin
hTaskLock.Enter;
//回收到最小设定线程
for k := High(IdleQueue) Downto FMinNums do
begin
TWorkThread(IdleQueue[k]).Terminate;
PostNewTaskSign;
end;
SetLength(IdleQueue,FMinNums);
hTaskLock.Leave;
end;
//定时完后线程释放
wait.Terminate;
FWaitFlag := True;
end;
procedure TThreadPool.RemoveFromQueue(var Queue: TWorkThreadQueue;
const re: TWorkThread);
var
index ,i: integer;
begin
index := -1;
for i := Low(Queue) to High(Queue) do
begin
if Queue[i] = re then
begin
index := i;
end;
end;
if Index<>-1 then
DelQueueOfIndex(Queue,index);
end;
procedure TThreadPool.RemoveTask(const tk: TWorkTask);
var
index:Integer;
begin
index := FindTask(tk);
if index = -1 then Exit;
hTaskLock.Enter;
DelTaskOfIndex(TaskQueue,index);
hTaskLock.Leave;
end;
{ TWorkThread }
constructor TWorkThread.Create(const pool: TThreadPool);
begin
FPool := pool;
SetDefault;
inherited Create(false);
end;
procedure TWorkThread.Execute;
var
hd:Array[0..0] of Cardinal;
ret:Cardinal;
task:TWorkTask;
nc:Integer;
begin
//不断的在任务队列中取任务
hd[0]:= fPool.entTaskNotify.Handle;
while not Terminated do
begin
//跟踪时为什么会暂停不了,是因为前面在设置MinNums时有信号增加
ret := WaitForMultipleObjects(1,@hd,false,INFINITE);
if Terminated then break;
Case ret - WAIT_OBJECT_0 of
WAIT_OBJECT_0:
begin
if state <> wtRunning then
begin
try
//抽取一个任务
task := FPool.PickupTask;
if assigned(task) then
begin
//任务启动前
if Assigned(fPool.FOnTaskWillDo) then
fPool.FOnTaskWillDo(self.ThreadID,task);
//需要线程同步,以防正在执行的任务被其它线程执行。
task.hTask.Enter;
//当有任务做时,将自己移到工作队列中
fPool.MoveQueue(self,0);
state := wtRunning;
//指定执行线程
task.Work := self;