很多人说:TThreadList不是存储了copy,而是reference,那么就象TList一样,可以存储对象指针。如果一个TThread对象execute结束了,并且freeonterminate:=false,那么把它放到ThreadList以后在再后来得到他的时候,怎样让他resume?也就是说怎样再让他执行一遍execute?既然是存储的reference,那就相当于一个thread execute以后再调用resume不会在执行execute一样啊!confused....
调试欢乐多
是指新建一个对象,或什么的,然后将另外一个对象的所有属性copy过来,那么新建的对象则有所有另外一个对象的属性,但是它是另外一个不同的值。reference:
一个引用关系,定义了一个对象,这个对象起到一个转接的关系,如果你访问它,其实就是访问它所指向的对象,所以你如果Free,也就是Free所指向的对象(不建议这么做) TThreadList一般说是: reference,指的就是引用已存在的对象,如Form1.Edit, Form1.Listbox2之类的东东,你会去Free这些东东吗?Thread.FreeOnTerminate 属性:
它是用于当一个线程完成后,定义是否消亡的标志,为什么,因为线程的execute如果执行完了,也就是一个线程的生命结束了,我们一般指定FreeOnTerminate为True,那么线程就会随Execute的完成而Free,所以当我们不需要可以设为True,让它自动Free,
但有时结束后,需要访问线程里面的值,如一些public的类型保存了一些我们需要的值,想在execute完成后使用,或想用进使用,那这个FreeOnTerminate := False了,它就不会因Execute而Free了,那就不会访问出错了。一般线程结束(execute)后会触发:
procedure OnTerminate; override; //写它的override事件
procedure OnTerminate; override; //写它的override事件
begin
inherited OnTerminate; //触发OnTerminated(Sender: Tobject)事件;
//do you code
end;execute完成就是一个线程完成,所以不存在Execute重复执行就能运行一个线程的说法,一般我们是在Execute来个大循环,通过Suspend,Resume来控制它Stop,run
让他resume?否则怎么使用这个已经execute结束的thread?////////////////////////////
注意:
当tthread.execute结束以后,线程运行结束了,但是freeonterminated:=false,则不会自动的释放线程对象,在这种情况下,再想让他执行一遍execute 用resume是不行的!/////////////////////////////////
我之所以不想在execute里面用循环检测terminated属性的办法,是因为我要先后使用多个线程对象,并且创建的时机使用户决定的,难道tthreadlist就是个摆设???
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
堂堂csdn没人会?
请不要说什么:CSDN没人,CSDN没高手会之类的话。
二:
如果别人回答的不好,请指出,请不要讥讽别人。
三:
我记得以前回答过你的问题,但没有结贴,使我“记得你”TThreadList只是一个收集器,收集一些会导致线程安全的控件、对象的容器,可以这么理解。使用时,只有两个重要的方法:
private
FLock: TThreadList;
...
end;
procedure SomeProc;
begin
FList.LockList;
try
这里进行线程对FList里面对象的访问,这里是线程安全。
FList通过Add, Remove方法进行对象的Add, Remove操作
finally
FList.UnlockList;
end;
end;注意:
SomeProc是全局函数,它是供线程访问的函数,而不是线程里面的函数/方法如果你看VCL源码,你会发现TThreadList其实就是TList and TCriticalSection的集成操作
我也不想这样说,可现状不得不让我这样说,要是在以前,这样的问题根本不会贴这么长时间!!难道就是因为你这个星级大侠给我回答过,就以为我在说你不是高手吗?二:
我没有讽刺你,哪个字看出来的?“帅哥”?你觉得在讽刺你什么?你帮我回答了,虽然没看清楚题目,但是我后面没谢你吗?三:
不但你回答我的问题,我不结贴,任何人回答我的问题我都可以不结贴!为啥??要是我能得到想要得答案,我会结贴的(我问的问题很多,少数顾不上结的除外,比起很多人来已经够意思了)!!就象这个问题一样,要我怎么结?tthreadlist用法help里面能查到,但是我最想知道的是:如果一个TThread对象execute结束了,并且freeonterminate:=false,那么把它放到ThreadList以后在再后来得到他的时候,怎样让他resume?也就是说怎样再让他执行一遍execute?既然是存储的reference,那就相当于一个thread execute以后再调用resume不会在执行execute一样啊!
之所以要存储线程对象,并且用TThreadList来存储,目的不就是为了减少线程的create次数么?下次再创建这个线程类的对象时,就不用create了,直接从threadlist里面得到先前已经创建好的,并且运行结束的线程对象。(因为同一个类的execute是一样的)这就是tthreadlist的作用?如果是这样,那么再次得到的先前创建好并执行完(freeonterminate:=false)的对象的时候怎样当作一个新创建的对象一样处理?
让他resume?否则怎么使用这个已经execute结束的thread?////////////////////////////////////////为什么就没人看清楚这些话呢?还有,即便会得罪人,我也想说出来,不吐不快!给别人回答问题为了什么?1。得分,让自己上星级,上专家榜。
2。帮助别人自己也快乐。
3。both of above.大家想想,自己为了什么?case the very purpose of
1:
begin
劝各位陌生气,即便故意不结你贴搂主的可用分也不会收回!我到想呢,csdn让吗?你不得分,别人回答的就会得分??大家都不得分你怕啥?上榜是按名次的!又不是按分!!
end;
2:
begin
热心帮助了别人,也要看看自己是不是真的帮助了,不要打着帮助的旗号,为了赚分!哪个问问题的不着急??
end;
3:
begin
既然想主观为得分+自己心里爽,客观帮别人,那就真正把问题回答好,能让搂主结贴!大家本来谁都不认识,又不是要你无偿回答!
end;
end;
/////////////////////////////////////////
我以前也上过段DFW,但发现那边气氛也不怎么样,怎么是除“非技术版”的,如果你是DFW来的,我可以体会。to stanely:
1: 我从来没说自已是高手,相反很多时间我是在看CSDN的贴子,因为我觉得我很菜
2:你不如看看我发的贴子,不管怎么样,我都会结贴,我觉得如果问题无解或回的不理想,我不会呆过一段时间的,不管如何。我不会因为别人做得怎么样,说:你看看他们,100个还没结过一个,就自已放任之。我理解你的意思,你所说的是线程池的实现,可你理解不够。
线程池这个概念从书上我也没看过,只是看过VCL的一些实现,知道一些情况。
大概的意思是说:实现线程取出,放回的功能,取出时从已有空闲的线程池里面取,如没有空闲则创建,创建数量和你设置的数量有关(要设个最大值,不能无限制),其中线程池我们可以看成是TList对象
还有我再说明:当TThread.Execute运行完成后,线程的生命就完了,不可能通过Resume进行恢复。
Windows线程是给VCL.TThread类封装了,将它的ThreadFunc封装到Execute 方法中,所以当Execute执行退出时,即是一个线程退出,线程完成。而ResumeThread, SuspendThread的使用是在ThreadFunc中,即在Execute。
线程池的实现有点复杂,有时间我帮你写个。如果你有空,可以到VCL\ScktComp.pas,就是那TServerSocket那个类看看,那有个线程池的实现。
TServerClientThread
它有一个KeepInCache的标志和Event: TEvent,注意这两个属性的动作
TServerWinSocket
管理上面Thread 的Pooler功能的
Windows, Messages, SysUtils, Classes, SyncObjs, ShellAPI;//{$DEFINE __EXIT}type
TPoolerManager = class; TPoolerThread = class(TThread)
private
FData: Pointer;
FEvent: THandle;
{$IFDEF __EXIT}
FExit: THandle;
{$ENDIF}
FKeepInCache: Boolean;
FManager: TPoolerManager;
procedure HandleException;
protected
function StartThread: Boolean;
function EndThread: Boolean;
procedure Run(Data: Pointer); virtual;
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean; AManager: TPoolerManager);
destructor Destroy; override;
procedure ReActive(Data: Pointer);
property Data: Pointer read FData;
property Event: THandle read FEvent;
property KeepInCache: Boolean read FKeepInCache write FKeepInCache;
end; TThreadEvent = procedure(AThread: TPoolerThread) of object;
TGetThreadEvent = procedure(AManager: TPoolerManager;
var AThread: TPoolerThread) of object; TPoolerManager = class
private
FMaxCount: Byte;
FThreadEnd: TThreadEvent;
FThreadStart: TThreadEvent;
FList: TList;
FLock: TCriticalSection;
FOnGetThread: TGetThreadEvent;
procedure DoThreadStart(Thread: TPoolerThread);
procedure DoThreadEnd(Thread: TPoolerThread);
procedure AddThread(Thread: TPoolerThread);
procedure RemoveThread(Thread: TPoolerThread);
procedure SetMaxCount(const Value: Byte);
function GetThreadCount: Integer;
function GetActiveThreadCount: Integer;
function GetItem(const Index: Integer): TPoolerThread;
public
constructor Create;
destructor Destroy; override;
function GetPoolerThread(Data: Pointer): TPoolerThread; virtual;
property OnGetThread: TGetThreadEvent read FOnGetThread write FOnGetThread;
property ThreadStart: TThreadEvent read FThreadStart write FThreadStart;
property ThreadEnd: TThreadEvent read FThreadEnd write FThreadEnd;
property Item[const Index: Integer]: TPoolerThread read GetItem;
property MaxCount: Byte read FMaxCount write SetMaxCount default 10;
property ThreadCount: Integer read GetThreadCount;
property ActiveThreadCount: Integer read GetActiveThreadCount;
end;implementation{ TPoolerThread }constructor TPoolerThread.Create(CreateSuspended: Boolean; AManager: TPoolerManager);
begin
FManager := AManager;
FKeepInCache := False;
FreeOnTerminate := True;
FEvent := CreateEvent(nil, True, False, nil);
{$IFDEF __EXIT}
FExit := CreateEvent(nil, False, False, nil);
{$ENDIF}
inherited Create(True);
ReActive(nil);
FManager.AddThread(Self);
if not CreateSuspended then Resume;
end;destructor TPoolerThread.Destroy;
begin
if Assigned(FManager) then
begin
FManager.RemoveThread(Self);
{$IFDEF __EXIT}
SetEvent(FExit);
{$ENDIF}
end;
CloseHandle(FEvent);
{$IFDEF __EXIT}
CloseHandle(FExit);
{$ENDIF}
inherited Destroy;
end;function TPoolerThread.EndThread: Boolean;
begin
FData := nil;
Result := Terminated or not FKeepInCache;
end;function TPoolerThread.StartThread: Boolean;
begin
if WaitForSingleObject(FEvent, INFINITE) = WAIT_OBJECT_0 then
ResetEvent(FEvent);
Result := not Terminated and Assigned(FData);
end;procedure TPoolerThread.HandleException;
var
E: Exception;
begin
E := Exception(ExceptObject);
if E is EAbort then Exit;
if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
if E is Exception then
begin
if Assigned(ApplicationShowException) then
ApplicationShowException(E);
end else
SysUtils.ShowException(E, nil);
end;procedure TPoolerThread.Run(Data: Pointer);
begin
// 重载此方法
// 保留一个Data: Pointer作为参数使用
end;procedure TPoolerThread.ReActive(Data: Pointer);
begin
FData := Data;
SetEvent(FEvent);
end;procedure TPoolerThread.Execute;
begin
FManager.DoThreadStart(Self);
try
try
while True do
begin
if StartThread then Run(FData);
if EndThread then break;
end;
except
KeepInCache := False;
Synchronize(HandleException);
end;
finally
FManager.DoThreadEnd(Self);
end;
end;{ TPoolerManager }procedure TPoolerManager.AddThread(Thread: TPoolerThread);
begin
FLock.Enter;
try
if FList.IndexOf(Thread) = -1 then
begin
FList.Add(Thread);
Thread.KeepInCache := FList.Count <= FMaxCount;
end;
finally
FLock.Leave;
end;
end;procedure TPoolerManager.RemoveThread(Thread: TPoolerThread);
begin
FLock.Enter;
try
FList.Remove(Thread);
finally
FLock.Leave;
end;
end;procedure TPoolerManager.DoThreadEnd(Thread: TPoolerThread);
begin
FLock.Enter;
try
if Assigned(FThreadEnd) then FThreadEnd(Thread);
finally
FLock.Leave;
end;
end;procedure TPoolerManager.DoThreadStart(Thread: TPoolerThread);
begin
FLock.Enter;
try
if Assigned(FThreadStart) then FThreadStart(Thread);
finally
FLock.Leave;
end;
end;constructor TPoolerManager.Create;
begin
inherited Create;
FLock := TCriticalSection.Create;
FList := TList.Create;
FMaxCount := 10;
end;destructor TPoolerManager.Destroy;
{$IFDEF __EXIT}
var
I: Integer;
{$ENDIF}
begin
{$IFDEF __EXIT}
for I := FList.Count - 1 downto 0 do { do not localize }
with TPoolerThread(FList[I]) do
begin
Terminate;
ReActive(nil);
WaitForSingleObject(FExit, INFINITE);
end;
{$ENDIF}
FList.Free;
FLock.Free;
inherited Destroy;
end;function TPoolerManager.GetPoolerThread(Data: Pointer): TPoolerThread;
var
I: Integer;
begin
Result := nil;
FLock.Enter;
try
for I := 0 to FList.Count - 1 do
if not Assigned(TPoolerThread(FList[I]).FData) then
begin
Result := FList[I];
break;
end;
finally
FLock.Leave;
end;
if not Assigned(Result) then
begin
if Assigned(FOnGetThread) then FOnGetThread(Self, Result);
if not Assigned(Result) then
Result := TPoolerThread.Create(False, Self);
end;
Result.ReActive(Data);
end;procedure TPoolerManager.SetMaxCount(const Value: Byte);
var
I, Start: Integer;
begin
if FMaxCount <> Value then
begin
if Value < FMaxCount then
Start := Value else
Start := FMaxCount;
FMaxCount := Value;
FLock.Enter;
try
for I := 0 to FList.Count - 1 do
TPoolerThread(FList[I]).KeepInCache := I < Start;
finally
FLock.Leave;
end;
end;
end;function TPoolerManager.GetThreadCount: Integer;
begin
FLock.Enter;
try
Result := FList.Count;
finally
FLock.Leave;
end;
end;function TPoolerManager.GetActiveThreadCount: Integer;
var
I: Integer;
begin
Result := 0;
FLock.Enter;
try
for I := 0 to FList.Count - 1 do
if Assigned(TPoolerThread(FList[I]).FData) then
Inc(Result);
finally
FLock.Leave;
end;
end;function TPoolerManager.GetItem(const Index: Integer): TPoolerThread;
begin
Result := FList[Index];
end;end.