有关TThread的FreeOnTerminte再次提问

kxy 2000-01-20 01:03:00
如果一个Thread在运行中,主程序结束,FreeOnTerminate没有
起作用,也就是说,Thread没有被释放,内存出现泄漏,如果Thread执行
完,主程序结束,Thread被释放.

OnFormClose中,Thread.Terminate,强制Thread结束也没有作用,
不知大家有没有好建议.

我是用,MemProof程序检查到内存泄漏的.
...全文
415 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
光明山人 2000-01-24
  • 打赏
  • 举报
回复
kxy, 我在http://www.midatech.com/csdn/expert/TopicView.asp?id=1029贴的一个例子中用到从主线程终止子线程的程序段,希望你能看看。
怎么说杀线程都是不太好,最好是协同工作,主线程通知子线程结束,并等待它们结束。子线程应当能检测Terminated属性,并退出Execute方法。

另外,终止线程还有一个比TerminateThread更安全的API函数:ExitThread,但我觉得最好的就是友好结束,好聚好散嘛,有话好说嘛。
kxy 2000-01-24
  • 打赏
  • 举报
回复
to : agui 我看了你的程序,
你可以试试Delphi demo中Thread的例子.
按照delphi的help可能会死锁.你试一试.
kxy 2000-01-23
  • 打赏
  • 举报
回复
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不可理喻:(
光明山人 2000-01-21
  • 打赏
  • 举报
回复
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的版本。
kxy 2000-01-21
  • 打赏
  • 举报
回复
to : barton
你可以编译delphi中的使用线程排序的例子,然后在正在排序
中关闭主窗口,(注意:是排序中),用MemProof检查试一试.
barton 2000-01-21
  • 打赏
  • 举报
回复
我认为不会。我也用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。
kxy 2000-01-20
  • 打赏
  • 举报
回复
>>如果一个Thread在运行中,主程序结束,FreeOnTerminate没有
>>起作用,也就是说,Thread没有被释放,内存出现泄漏,如果Thread执行
>>完,主程序结束,Thread被释放.
谢谢agui不过你没有看清楚我的问题.

光明山人 2000-01-20
  • 打赏
  • 举报
回复
其实强行结束线程是不正常的做法,除非发生了异常(如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。
kxy 2000-01-20
  • 打赏
  • 举报
回复
VC可以用BoundsCheck,
www.csdn.net 开发工具中有介绍.
至于哪里能找到,:) 买我们的光盘吧:)
76yyj 2000-01-20
  • 打赏
  • 举报
回复
Terminate方法只是把TThread的Terminated属性设置为True,表示相应的TThread在可能的时候结束,此方法不起强制关闭线程的作用。
可以试一下用Windows API函数ExitThread,它可以强制关闭线程。
具体用法大致可分为两步:
1 用GetExitCodeThread函数获取lpExitCode;
2 用ExitThread(lpExitCode)结束相应线程。
netsky 2000-01-20
  • 打赏
  • 举报
回复
不好意思我不能回答你的问题,我还想向你提一个问题,MemProof是针对BC,DELPHI的,有没有针对的VC的检测程序呢?是在哪里?谢谢
Venne 2000-01-20
  • 打赏
  • 举报
回复
TThead对象的句柄是不是一个可以用来侦测的值呢?我没有实际去试过,我试试,再讨论吧!
kxy 2000-01-20
  • 打赏
  • 举报
回复
http://www.totalqa.com/download/index.htm
It's Free
NowCan 2000-01-20
  • 打赏
  • 举报
回复
请问MemProof程序哪里有?告诉我好吗? Email:liukai1111@263.net
kxy 2000-01-20
  • 打赏
  • 举报
回复
TThread的Terminate只是把一个变量赋值没有执行什么.我看了Source
WINDOWS API 函数TerminateThread会结束Thread,内存会不会释放?

我想手工释放是可行的.只是怎么发现有线程在运行,我用的是LMDHiTimer
又懒的再去改它的source. LMDHiTimer是有内存泄漏.
Venne 2000-01-20
  • 打赏
  • 举报
回复
是否是使用的TThread对象呢?
记得调用其Terminate方法不会立刻关闭线程换用WINDOWS API 函数TerminateThread试一下,如果有线程在运行,KILL IT!
:)

5,379

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧