发一个自用的基于匿名函数的简易线程池
delphi吧
全部回复
仅看楼主
吧务
level 14
BambooCaep 楼主
unit BambooThread.PoolLite;
interface
uses
System.SysUtils;
type
TInterface_BambooThreadPoolLite = interface
function Runing: Boolean;
procedure ClearProc;
procedure ThreadStart(aProc: TProc);
end;
function Create_BambooThreadPool(aMaxThreadCount: Byte): TInterface_BambooThreadPoolLite;
implementation
uses
System.Classes,
System.Generics.Collections;
type
TBambooThreadPoolLite = class;
TCacheThread = class(TThread)
private
FThreadPool: TBambooThreadPoolLite;
FProc: TProc;
protected
procedure Execute; override;
procedure Do_Resume;
public
constructor Create(aThreadPool: TBambooThreadPoolLite);
end;
TBambooThreadPoolLite = class(TInterfacedObject, TInterface_BambooThreadPoolLite)
private type
TItem_Proc = record
FProc: TProc;
end;
private
FLock: TObject;
FQueue_Thread: TQueue<TCacheThread>;
FQueue_Proc: TQueue<TItem_Proc>;
FUsedCount: Integer;
FMaxThreadCount: Byte;
FCreateCount: Integer;
private
function TryDequeueProc(var aProc: TProc): Boolean;
function TryDequeueThread(var aThread: TCacheThread): Boolean;
procedure Do_Proc_Queue;
function Internal_Get_Thread: TCacheThread;
function Internal_Do_Start_Queue(aForceThread: Boolean): Boolean;
private
function Runing: Boolean;
procedure ClearProc;
procedure ThreadStart(aProc: TProc);
public
constructor Create(aMaxThreadCount: Byte);
destructor Destroy; override;
end;
function Create_BambooThreadPool(aMaxThreadCount: Byte): TInterface_BambooThreadPoolLite;
begin
Result := TBambooThreadPoolLite.Create(aMaxThreadCount);
end;
{ TCacheThread }
constructor TCacheThread.Create(aThreadPool: TBambooThreadPoolLite);
begin
inherited Create(True);
FThreadPool := aThreadPool;
FreeOnTerminate := False;
end;
procedure TCacheThread.Do_Resume;
begin
while Suspended do
Suspended := False;
end;
procedure TCacheThread.Execute;
begin
while not Terminated do
begin
try
if Assigned(FProc) then
FProc;
except
end;
FProc := nil;
with FThreadPool do
begin
TMonitor.Enter(FLock);
Internal_Do_Start_Queue(True);
FQueue_Thread.Enqueue(Self);
Dec(FUsedCount);
TMonitor.Exit(FLock);
end;
Suspended := True;
end;
end;
{ TBambooThreadPoolLite }
procedure TBambooThreadPoolLite.ClearProc;
begin
TMonitor.Enter(FLock);
FQueue_Proc.Clear;
TMonitor.Exit(FLock);
end;
constructor TBambooThreadPoolLite.Create(aMaxThreadCount: Byte);
begin
inherited Create;
FMaxThreadCount := aMaxThreadCount;
FLock := TObject.Create;
FQueue_Thread := TQueue<TCacheThread>.Create;
FQueue_Proc := TQueue<TItem_Proc>.Create;
FMaxThreadCount := aMaxThreadCount;
if FMaxThreadCount = 0 then
FMaxThreadCount := 1;
end;
destructor TBambooThreadPoolLite.Destroy;
var
aThread: TCacheThread;
begin
while Runing do
Sleep(10);
TMonitor.Enter(FLock);
try
while TryDequeueThread(aThread) do
begin
while not aThread.Suspended do
Sleep(0);
aThread.Terminate;
aThread.Do_Resume;
aThread.WaitFor;
aThread.Free;
end;
FQueue_Thread.Free;
FQueue_Proc.Free;
inherited Destroy;
finally
TMonitor.Exit(FLock);
FLock.Free;
end;
end;
procedure TBambooThreadPoolLite.Do_Proc_Queue;
var
aHaveNew: Boolean;
aProc: TProc;
begin
repeat
TMonitor.Enter(FLock);
aHaveNew := TryDequeueProc(aProc);
TMonitor.Exit(FLock);
if aHaveNew then
try
aProc;
except
end;
until not aHaveNew;
end;
function TBambooThreadPoolLite.Internal_Do_Start_Queue(aForceThread: Boolean): Boolean;
var
aThread: TCacheThread;
begin
Result := (FQueue_Proc.Count > 0) and (aForceThread or (FUsedCount < FMaxThreadCount));
if Result then
begin
Inc(FUsedCount);
aThread := Internal_Get_Thread;
aThread.FProc := Do_Proc_Queue;
aThread.Do_Resume;
end;
end;
function TBambooThreadPoolLite.Internal_Get_Thread: TCacheThread;
begin
if not TryDequeueThread(Result) then
begin
Result := TCacheThread.Create(Self);
Inc(FCreateCount);
end;
while not Result.Suspended do
Sleep(0);
end;
function TBambooThreadPoolLite.Runing: Boolean;
begin
TMonitor.Enter(FLock);
Result := FCreateCount > FQueue_Thread.Count;
TMonitor.Exit(FLock);
end;
procedure TBambooThreadPoolLite.ThreadStart(aProc: TProc);
var
aItem_Proc: TItem_Proc;
begin
if not Assigned(aProc) then
Exit;
TMonitor.Enter(FLock);
aItem_Proc.FProc := aProc;
FQueue_Proc.Enqueue(aItem_Proc);
Internal_Do_Start_Queue(False);
TMonitor.Exit(FLock);
end;
function TBambooThreadPoolLite.TryDequeueProc(var aProc: TProc): Boolean;
var
aItem_Proc: TItem_Proc;
begin
Result := FQueue_Proc.Count > 0;
if Result then
begin
aItem_Proc := FQueue_Proc.Dequeue;
aProc := aItem_Proc.FProc;
end;
end;
function TBambooThreadPoolLite.TryDequeueThread(var aThread: TCacheThread): Boolean;
begin
Result := FQueue_Thread.Count > 0;
if Result then
aThread := FQueue_Thread.Dequeue;
end;
end.
2014年08月29日 02点08分 1
吧务
level 14
BambooCaep 楼主
下面是一个功能扩展的示例:
unit BambooThread.Helper;
interface
uses
BambooThread.Defaults,
System.SysUtils;
type
TBambooHelper_ThreadPool = record
class procedure ThreadStart<T>(aThreadPool: TInterface_BambooThreadPool; const aID: T; aProc: TProc<T>); static;
end;
implementation
{ TBambooHelper_ThreadPool }
class procedure TBambooHelper_ThreadPool.ThreadStart<T>(aThreadPool: TInterface_BambooThreadPool; const aID: T; aProc: TProc<T>);
begin
if Assigned(aThreadPool) and Assigned(aProc) then
aThreadPool.ThreadStart(
procedure
begin
aProc(aID);
end);
end;
end.
2014年08月29日 02点08分 3
level 11
火钳刘明
2014年08月29日 06点08分 4
level 11
要发就发完整代码,要不就对自己的代码功能加个简要说明,不然这帖毫无意义!
2014年08月29日 09点08分 5
白痴!
2014年08月29日 10点08分
这个还不完整?你想怎样?
2014年08月29日 17点08分
自己看看BambooThread.Defaults是写在什么地方?看来你俩是一起的吧,既然都能用。自吹自擂有意思么?发堆没用的
2014年08月30日 01点08分
回复 阳光和青草 :所以说你是个白痴!
2014年08月30日 03点08分
level 11
今天刚才百度首页看了个桥布斯跟莫大师的事,不愧是桥布斯,激进的人也有细致的一面。
不象某些人发个不带注释不知所云的帖子,自己开个号来吹,似乎别人都必须要看懂理解他所写的东西似的。
好好跟万一老师学学吧,学学人家是怎么表达的,不是每个人都有工夫跟这不白痴的大师去讲什么东西的。
2014年08月30日 04点08分 7
滚!这帖子不是给你这种白痴看的!
2014年08月30日 04点08分
还什么开小号,你脑子是豆腐渣做的?你就不会点开那个名字看看资料?
2014年08月30日 04点08分
你丫是来秀下限的吧!
2014年08月30日 05点08分
回复 BambooCaep :你是来秀下限的才对[喷]
2014年08月30日 06点08分
level 13
好高级,我都没用过这种……
2014年08月30日 05点08分 8
自己写的,拿来做并行计算。
2014年08月30日 05点08分
回复 BambooCaep :这方面我确实没经验,见笑
2014年08月30日 05点08分
主要是考虑到跨平台,所以没有使用任何windows下特有的东西。这个是简化版,因为完整版用到了许多我自己写的其它单元。
2014年08月30日 05点08分
我也是写着玩的,最初的用途是写了一个android下的多线程五子棋程序,需要并行计算。
2014年08月30日 05点08分
level 11
自以为很厉害听不进去别人意见不会好好说话
2014年08月30日 06点08分 9
他那算哪门子的意见?不信你可以把1楼的代码编译一次,看看到底完整不完整?
2014年08月30日 06点08分
回复 BambooCaep :我说的不是那个
2014年08月30日 06点08分
回复 wfwhl12 :你说7楼?他看不懂的就叫不知所云?那delphi的源代码他一定都看懂了,不然他怎么不说delphi那些源代码不知所云呢?
2014年08月30日 06点08分
回复 BambooCaep :算了算了,您最厉害
2014年08月30日 07点08分
level 14
先顶后看,学习下
2014年09月02日 01点09分 10
level 12
笑死 还是吧主 先不管别人说的对不对 张口闭口就喷人 太喜感了[狂笑]
2014年09月02日 01点09分 11
伸手党来喷别人没让他看懂,签到党也出来找存在感了?[鄙视]
2014年09月02日 02点09分
回复 BambooCaep :你优越感还真强 太搞笑了
2014年09月02日 02点09分
回复 zfei19831104 :你有本事找出我代码的问题再来跟我说优越感的问题吧!
2014年09月02日 02点09分
回复 zfei19831104 :别跟那个SB伸手党一样这么几行代码都看不懂就来喷。
2014年09月02日 02点09分
level 12
大家都是老家伙了,何必掐起来,各省一句就好
2014年09月02日 03点09分 12
那是因为SB伸手党先开喷啊。
2014年09月02日 03点09分
level 2
围观中..
2014年09月12日 02点09分 13
level 13
这是战贴吗?哈哈[吐舌]
你这个线程池还少了一点东西啊,就是对假死线程的处理,不然多任务处理时,很容易卡死整个应用。。。
2014年09月16日 18点09分 14
我发的是lite版。
2014年09月17日 00点09分
level 1
可以解说下意思吗
2015年04月22日 09点04分 15
参照 TThread.CreateAnonymousThread方法。
2015年04月22日 10点04分
至于线程池的含义请自行百度
2015年04月22日 10点04分
level 7
不错
2016年04月13日 03点04分 16
level 5
没注释 看不懂 另外楼主这么清高 发出来干什么都不懂 这里基本都是小白
2016年08月31日 08点08分 17
你不懂不代表别人都看不懂
2016年08月31日 08点08分
@Make_me_Laugh 你可以滚出本吧了
2016年08月31日 14点08分
@BambooCaep [滑稽]权限狗,贴吧不是用来给你装逼的
2016年08月31日 16点08分
@哈尔滨的夜猫子 人身攻击,你也一样。
2016年08月31日 18点08分
level 7
Delphi XE7开始,已经有System.Threading单元,RTL有线程池了
2017年02月01日 11点02分 18
呃,我写这个程序的时候还木有threading
2017年02月01日 12点02分
@BambooCaep 好吧,不过新版本里最好用System.Threading
2017年02月01日 13点02分
@aaa555555554 简单点的需求我就threading了。
2017年02月01日 13点02分
@aaa555555554 我发出来的是lite版,完整版包括了假死线程处理等控制。另外还有一大堆辅助功能,比如用10来个线程去控制成千上万个循环。
2017年02月01日 14点02分
level 4
线程池用qworker吧
2017年04月26日 04点04分 19
1