异步任务调度
异步任务调度
适用于DELPHI2009及以上版本,支持跨操作系统。
/// <author>cxg 2020-7-13</author>
/// 异步任务调度
{使用:
procedure TForm1.Button1Click(Sender: TObject);
begin
var task: TMsgPack := TMsgPack.Create;
task.Force('f1').AsString := '测试';
var queue: TTaskQueue := TTaskQueue.Create;
queue.enQueue(task);
var tasks: TThreadCfg := TThreadCfg.Create(1, queue,
procedure(task: TMsgPack)
begin
ShowMessage(task.Force('f1').AsString);
tasks.Free;
end);
end;
}
unit tasks;
interface
uses
{$IFDEF mswindows}
Winapi.Windows,
{$ENDIF}
{$IFDEF posix}
posix.Unistd,
{$ENDIF}
System.SyncObjs, System.Classes, System.SysUtils, System.Generics.Collections,
MsgPack;
type
TCallBack = reference to procedure(task: TMsgPack);
type
TTaskQueue = class //任务队列(线程安全)
private
fQueue: TQueue<TMsgPack>;
fCS: TCriticalSection;
public
constructor Create;
destructor Destroy; override;
procedure enQueue(task: TMsgPack);
function deQueue: TMsgPack;
end;
type
TThreadCfg = class //管理 工作线程
private
fQueue: TTaskQueue;
fCallBack: TCallBack;
fThreadNum: Integer;
fWorkers: array of TThread;
public
constructor Create(const threadNum: Integer; const queue: TTaskQueue; CallbackEvent: TCallBack);
destructor Destroy; override;
end;
type
TWorkThread = class(TThread) //工作线程
private
fConfig: TThreadCfg;
public
constructor Create(cfg: TThreadCfg);
destructor Destroy; override;
procedure Execute; override;
end;
implementation
function GetCPUNum: Integer;
{$IFDEF MSWINDOWS}
var
si: SYSTEM_INFO;
{$ENDIF}
begin
{$IFDEF MSWINDOWS}
GetSystemInfo(si);
Result := si.dwNumberOfProcessors;
{$ELSE}// Linux,MacOS,iOS,Andriod{POSIX}
{$IFDEF POSIX}
Result := sysconf(_SC_NPROCESSORS_ONLN);
{$ELSE}// unkown system, default 1
Result := 5;
{$ENDIF POSIX}
{$ENDIF MSWINDOWS}
end;
{ TTaskQueue }
constructor TTaskQueue.Create;
begin
fQueue := TQueue<TMsgPack>.Create;
fCS := TCriticalSection.Create;
end;
destructor TTaskQueue.Destroy;
begin
FreeAndNil(fQueue);
FreeAndNil(fCS);
inherited;
end;
procedure TTaskQueue.enQueue(task: TMsgPack);
begin
fCS.Enter;
fQueue.Enqueue(task);
fCS.Leave;
end;
function TTaskQueue.deQueue: TMsgPack;
begin
fCS.Enter;
Result := fQueue.Dequeue;
fCS.Leave;
end;
{ TWorkThread }
constructor TWorkThread.Create(cfg: TThreadCfg);
begin
inherited Create(True);
FreeOnTerminate := true;
fConfig := cfg;
end;
destructor TWorkThread.Destroy;
begin
inherited;
end;
procedure TWorkThread.Execute;
begin
while not Self.Terminated do
begin
if fConfig.fQueue.fQueue.Count > 0 then
begin
var task: TMsgPack := fConfig.fQueue.deQueue;
if Assigned(fConfig.fCallBack) then
begin
fConfig.fCallBack(task);
task.Free; //释放
end;
end;
Sleep(1);
{$IFDEF MSWINDOWS}
SwitchToThread;
{$ELSE}
TThread.Yield;
{$ENDIF}
end;
end;
{ TThreadCfg }
constructor TThreadCfg.Create(const threadNum: Integer; const queue: TTaskQueue; CallbackEvent: TCallBack);
begin
fThreadNum := threadNum;
fQueue := queue;
fCallBack := CallbackEvent;
if fThreadNum = 0 then
fThreadNum := GetCPUNum;
SetLength(fWorkers, fThreadNum);
for var i: Integer := 0 to fThreadNum - 1 do
begin
fWorkers[i] := TWorkThread.Create(Self);
fWorkers[i].Start;
end;
end;
destructor TThreadCfg.Destroy;
begin
for var i: Integer := 0 to fThreadNum - 1 do //停止并释放工作线程
begin
fWorkers[i].Terminate;
fWorkers[i].WaitFor;
fWorkers[i].Free;
end;
fQueue.Free; //释放队列
inherited;
end;
end.
本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/p/13294946.html

浙公网安备 33010602011771号