TThread的Terminate只是把一个变量赋值没有执行什么.我看了Source WINDOWS API 函数TerminateThread会结束Thread,内存会不会释放?我想手工释放是可行的.只是怎么发现有线程在运行,我用的是LMDHiTimer 又懒的再去改它的source. LMDHiTimer是有内存泄漏.
其实强行结束线程是不正常的做法,除非发生了异常(如WINDOWS中除非程序死了,你才会用非常手段杀死该进程,如CTRL+ALT+DELETE),才能使用那样的绝招。Delphi的帮助写得很清楚: Execute is responsible for checking the value of the Terminated property to determine if the thread needs to exit.就是说你写的Thread派生类必须override Execute方法,而你的方法中必须检测Terminated属性是否为TRUE,若是就必须退出Execute方法。通常Execute方法是一个循环,你应当把Terminated属性作为退出循环的充分条件。当Execute退出时,线程就结束了。多数Execute会这样写: while not Terminated do begin ... end;线程结束并不表示线程对象被释放,如果设置了FreeOnTerminate,则自动释放(这时记得别再使用该对象的指针了。)如果FreeOnTerminate为FALSE,则必须手工执行:Thread.Free。
我认为不会。我也用MemProof检测过我的线程,设置过FreeOnTerminate为True, 总是释放。我用线程的方法似乎不用考虑同步。因为我总是写: TMyProcedure = procedure of object; TMyThread = class(TThread) private FOnActive: TMyProcedure; protected procedure Execute; override; Public constructor Create(AProc: TMyProcedure); end; constructor TMyThread.Create(AProc: TMyProcedure); begin FOnActive := AProc; inherited Create(False); end; procedure TMyThread.Execute; begin FreeOnTerminate := True; if Assigned(FOnAvtive) then FOnActive; end; 然后设定的AProc方法是外部方法,在这个方法中检测Terminated没有意义, 所以如果我的方法中是一个不能自行中止的循环的话我总是自己建立一个标志 变量,在循环中检测。要中止循环的话,只需设置这个变量为True即可。如果设置了FreeOnTerminate为True,线程后肯定会释放。如果事实上没有释放 的话,只有一种可能:线程没有结束。当然线程没有结束的原因很多。不必去 调用API,因为TThread就是调用的API。
to : barton 你可以编译delphi中的使用线程排序的例子,然后在正在排序 中关闭主窗口,(注意:是排序中),用MemProof检查试一试.
to kxy: sorry, I mistaked.建议不要使用FreeOnTerminate。 你可以试试在FormCloseQuery中这样写(当然我也试试): Thread.Terminate; while ThreadActive(Thread.Handle) do Application.ProcessMessages;
Thread.Free;但是这样做的前提是Execute方法必须检测Terminated属性。 ThreadActive函数如下:function ThreadActive( aThread: THandle ): Boolean; var ExitCode: Integer; // 也许是用LongWord,我没仔细查pas文件 begin GetExitCodeThread( aThread, ExitCode ); Result := (STILL_ACTIVE=ExitCode); end; BTW: BoundChecker也有For Delphi的版本。
1)[美] Jeffrey Richter Windows NT 高级编程技术. 中提到: 当线程是由于自然原因或自杀而死亡时,该线程中的堆栈将被撤销. 但是该线程如果是他杀(调用TeriminateThread),windows在拥有该 线程的进程退出之前不会撤销该堆栈. 另外,在线程终止时,windows将通知所有挂接在这个拥有终止线程的 进程上的Dlls,告诉它们线程将被终止.但是他杀的不会.例如,在线程 脱离与某个Dll的挂接时,该Dll可能要往磁盘上刷新数据,如果dll 没有得到通知,..... 同样TerminateProcess也是一样的. 由此,不到万不得已,不要使用TerminteThred和TerimnateProcess!!!!! 2)Delphi中有关Wait的帮助中提到: Don't call WaitFor in the context of the main VCL thread if the thread uses Synchronize. Doing so will either cause a deadlock, making it appear that the application has hung, or raise an EThread exception. TMD不可理喻:(
WINDOWS API 函数TerminateThread会结束Thread,内存会不会释放?我想手工释放是可行的.只是怎么发现有线程在运行,我用的是LMDHiTimer
又懒的再去改它的source. LMDHiTimer是有内存泄漏.
It's Free
可以试一下用Windows API函数ExitThread,它可以强制关闭线程。
具体用法大致可分为两步:
1 用GetExitCodeThread函数获取lpExitCode;
2 用ExitThread(lpExitCode)结束相应线程。
www.csdn.net 开发工具中有介绍.
至于哪里能找到,:) 买我们的光盘吧:)
Execute is responsible for checking the value of the Terminated property to determine if the thread needs to exit.就是说你写的Thread派生类必须override Execute方法,而你的方法中必须检测Terminated属性是否为TRUE,若是就必须退出Execute方法。通常Execute方法是一个循环,你应当把Terminated属性作为退出循环的充分条件。当Execute退出时,线程就结束了。多数Execute会这样写:
while not Terminated do
begin
...
end;线程结束并不表示线程对象被释放,如果设置了FreeOnTerminate,则自动释放(这时记得别再使用该对象的指针了。)如果FreeOnTerminate为FALSE,则必须手工执行:Thread.Free。
>>起作用,也就是说,Thread没有被释放,内存出现泄漏,如果Thread执行
>>完,主程序结束,Thread被释放.
谢谢agui不过你没有看清楚我的问题.
总是释放。我用线程的方法似乎不用考虑同步。因为我总是写: TMyProcedure = procedure of object; TMyThread = class(TThread)
private
FOnActive: TMyProcedure;
protected
procedure Execute; override;
Public
constructor Create(AProc: TMyProcedure);
end; constructor TMyThread.Create(AProc: TMyProcedure);
begin
FOnActive := AProc;
inherited Create(False);
end; procedure TMyThread.Execute;
begin
FreeOnTerminate := True;
if Assigned(FOnAvtive) then FOnActive;
end; 然后设定的AProc方法是外部方法,在这个方法中检测Terminated没有意义,
所以如果我的方法中是一个不能自行中止的循环的话我总是自己建立一个标志
变量,在循环中检测。要中止循环的话,只需设置这个变量为True即可。如果设置了FreeOnTerminate为True,线程后肯定会释放。如果事实上没有释放
的话,只有一种可能:线程没有结束。当然线程没有结束的原因很多。不必去
调用API,因为TThread就是调用的API。
你可以编译delphi中的使用线程排序的例子,然后在正在排序
中关闭主窗口,(注意:是排序中),用MemProof检查试一试.
你可以试试在FormCloseQuery中这样写(当然我也试试):
Thread.Terminate;
while ThreadActive(Thread.Handle) do
Application.ProcessMessages;
Thread.Free;但是这样做的前提是Execute方法必须检测Terminated属性。
ThreadActive函数如下:function ThreadActive( aThread: THandle ): Boolean;
var
ExitCode: Integer; // 也许是用LongWord,我没仔细查pas文件
begin
GetExitCodeThread( aThread, ExitCode );
Result := (STILL_ACTIVE=ExitCode);
end; BTW: BoundChecker也有For Delphi的版本。
Windows NT 高级编程技术.
中提到:
当线程是由于自然原因或自杀而死亡时,该线程中的堆栈将被撤销.
但是该线程如果是他杀(调用TeriminateThread),windows在拥有该
线程的进程退出之前不会撤销该堆栈.
另外,在线程终止时,windows将通知所有挂接在这个拥有终止线程的
进程上的Dlls,告诉它们线程将被终止.但是他杀的不会.例如,在线程
脱离与某个Dll的挂接时,该Dll可能要往磁盘上刷新数据,如果dll
没有得到通知,.....
同样TerminateProcess也是一样的.
由此,不到万不得已,不要使用TerminteThred和TerimnateProcess!!!!!
2)Delphi中有关Wait的帮助中提到:
Don't call WaitFor in the context of the main VCL thread if the thread uses Synchronize. Doing so will either cause a deadlock, making it appear that the application has hung, or raise an EThread exception.
TMD不可理喻:(
怎么说杀线程都是不太好,最好是协同工作,主线程通知子线程结束,并等待它们结束。子线程应当能检测Terminated属性,并退出Execute方法。另外,终止线程还有一个比TerminateThread更安全的API函数:ExitThread,但我觉得最好的就是友好结束,好聚好散嘛,有话好说嘛。
你可以试试Delphi demo中Thread的例子.
按照delphi的help可能会死锁.你试一试.