线程池

线程池

/// <author>cxg 2023-6-19</author>
/// 异步任务队列调度
/// 每个线程都有自己的任务队列
/// 处理任务均衡算法:依次往每个线程的队列投递任务,线程从自己的队列中获取任务处理

unit tasks;

interface

uses
  Windows, Contnrs, SyncObjs, Classes, SysUtils;

type
  TCallBack = procedure(task: Pointer) of object;

type
  TThreadConf = class
  private
    fCallBack: TCallBack;
    fThreadNum: integer;
    threads: array of TThread;
    lock: TCriticalSection;
    procedure freeThreads;
    procedure newThreads;
  public
    constructor Create(const threadNum: integer = 0);
    destructor Destroy; override;
  public
    procedure startThreads;
    procedure stopThreads;
    procedure push(task: Pointer);
  public
    property onCallback: TCallBack read fCallBack write fCallBack;
    property threadNum: integer read fThreadNum;
  end;

type
  TWorkThread = class(TThread)
  private
    fConf: TThreadConf;
    fQueue: TQueue;
  public
    constructor Create(conf: TThreadConf);
    destructor Destroy; override;
  public
    procedure Execute; override;
    procedure push(task: Pointer);
  end;

implementation

var
  gIndex: Integer = 0;

{ TThreadConf }

procedure TThreadConf.push(task: Pointer);
var
  i: Integer;
begin
  lock.Enter;
  try
    i := gIndex mod fThreadNum;    //轮循算法
    inc(gIndex);
  finally
    lock.Leave;
  end;
  TWorkThread(threads[i]).push(task);
end;

constructor TThreadConf.Create(const threadNum: integer = 0);
begin
  lock := TCriticalSection.Create;
  fThreadNum := threadNum;
  if fThreadNum = 0 then
    fThreadNum := cpucount;
  SetLength(threads, fThreadNum);
  newThreads;
end;

destructor TThreadConf.Destroy;
begin
  freeThreads;
  FreeAndNil(lock);
  inherited;
end;

procedure TThreadConf.freeThreads;
var
  thread: tthread;
begin
  for thread in threads do
  begin
    thread.Terminate;
    thread.WaitFor;
    freeandnil(thread);
  end;
end;

procedure TThreadConf.newThreads;
var
  i: Byte;
begin
  for i := 0 to fThreadNum - 1 do
    threads[i] := TWorkThread.Create(Self);
end;

procedure TThreadConf.startThreads;
var
  thread: tthread;
begin
  for thread in threads do
    thread.Start;
end;

procedure TThreadConf.stopThreads;
var
  thread: tthread;
begin
  for thread in threads do
    thread.Suspend;
end;

{ TWorkThread }

constructor TWorkThread.Create(conf: TThreadConf);
begin
  inherited Create(true);
  FreeOnTerminate := True;
  fConf := conf;
  fQueue := TQueue.Create;
end;

destructor TWorkThread.Destroy;
begin
  FreeAndNil(fQueue);
  inherited;
end;

procedure TWorkThread.push(task: Pointer);
begin
  fQueue.Push(task);
end;

procedure TWorkThread.Execute;
var
  task: Pointer;
begin
  while not Self.Terminated do
  begin
    task := fQueue.Pop;
    if task <> nil then
      if Assigned(fConf.fCallBack) then
        fConf.fCallBack(task);
    sleep(1);
  end;
end;

end.

 

posted @ 2023-06-18 10:16  delphi中间件  阅读(199)  评论(0编辑  收藏  举报