线程池任务队列(七)

2014-11-24 10:13:24 · 作者: · 浏览: 3
hIDleLock.Leave;
end;

procedure TThreadPool.AddThreadToBusyQueue(const busy: TWorkThread);
var
sz:integer;
begin
sz := QueueSize(BusyQueue);
setLength(BusyQueue,sz + 1);
BusyQueue[sz] := busy;
end;

procedure TThreadPool.AddThreadToIdleQueue(const idle: TWorkThread);
var
sz:integer;
begin
sz := Length(IdleQueue);
setLength(IdleQueue,sz + 1);
IdleQueue[sz] := idle;
end;

function TThreadPool.PickupTask: TWorkTask;
begin
//先排序再取
hTaskLock.enter;

if FSorted then
SortTask(TaskQueue);

if length(TaskQueue) > 0 then
begin
Result := TaskQueue[0];
DelTaskOfIndex(TaskQueue,0);
end
else
Result := Nil;
hTaskLock.Leave;
end;

function TThreadPool.AddWorkTask(Const wtask: TWorkTask):Integer;
var
sz,ic,bc:Integer;
begin
sz := Length(TaskQueue);
if sz >= FTasksCache then
begin
Result := -1;
DoTaskFull;
exit;
end;

setLength(TaskQueue,sz+1);
wtask.WorkState := tsWaiting;
TaskQueue[sz] := wtask;

Result := sz + 1;

//未达到最大线程数时增加
ic := IdleQueueCount;
bc := BusyQueueCount;

//最大只能ic + bc = MaxNums
if (ic = 0) and (ic+ bc < FMaxNums) then
CreateIdleThread();

FAuto := True;
//通知线程去取任务
PostNewTaskSign;
Log.WriteLog('Add a task to queue.',lInfo);
end;

function TThreadPool.FindTask(const tsk: TWorkTask): Integer;
var
l:Integer;
begin
Result := -1;
for l := Low(TaskQueue) to High(TaskQueue) do
if TaskQueue[l] = tsk then
begin
Result := l;
Break;
end;
end;

procedure TThreadPool.PostNewTaskSign;
begin
entTaskNotify.SetEvent;
end;

procedure TThreadPool.switch(var Queue:TWorkTaskQueue;m,n:Integer);
var
tem:TWorkTask;
begin
tem := Queue[m];
Queue[m] := Queue[n];
Queue[n] := tem;
end;

procedure TThreadPool.QuikeSortTask(var Queue: TWorkTaskQueue; const s,
e: Integer);
var
key:Integer;
k,j:Integer;
begin
key := ord(Queue[s].WorkLevel);

if s > e then exit;

k := s;
j := e;

while (k <> j) do
begin
while (k < j) and (ord(Queue[j].WorkLevel) <= key) do //如果排序从小到大时改为 >=
dec(j);
switch(Queue,k,j);

while (k < j) and (ord(Queue[k].WorkLevel) >= key) do //如果排序从小到大时改为 <=
inc(k);
Switch(Queue,j,k);
end;

if s < k-1 then
QuikeSortTask(Queue,s,k-1);
if k+1 < e then
QuikeSortTask(Queue,k+1,e);
end;

procedure TThreadPool.SortTask(var Queue: TWorkTaskQueue);
var
f,l:Integer;
ic:Integer;
begin
ic := Length(Queue);
if ic = 0 then exit;

if Assigned(FOnSortTask) then
FOnSortTask(self,Queue)
else
begin
f := 0;
l := ic-1;
QuikeSortTask(Queue,f,l);
end;
end;

procedure TThreadPool.StartAll;
var
I:Integer;
begin
hBusyLock.Enter;
for I := Low(BusyQueue) to High(BusyQueue) do
begin
BusyQueue[i].Resume;
BusyQueue[i].State := wtRunning;
end;
hBusyLock.Leave;

hIDleLock.Enter;
for I := Low(IdleQueue) to High(IdleQueue) do
begin
IdleQueue[i].Resume;
IdleQueue[i].State := wtRunning;
end;
hIDleLock.Leave;
end;

procedure TThreadPool.StopAll;
var
I:Integer;
begin
hBusyLock.Enter;
for I := Low(BusyQueue) to High(BusyQueue) do
be