线程释放问题 ( 积分: 300 )

  • 主题发起人 主题发起人 muhx
  • 开始时间 开始时间
M

muhx

Unregistered / Unconfirmed
GUEST, unregistred user!
怎样才能最安全的释放一个线程?
比如线程的执行部分是一个死循环,在程序关闭之前要先释放这个线程,怎样才能做到安全的释放呢?
现在我的一个程序中包括20个线程,我必须做到每个线程都安全的释放
请大家帮忙,放分我从不吝啬:)
 
怎样才能最安全的释放一个线程?
比如线程的执行部分是一个死循环,在程序关闭之前要先释放这个线程,怎样才能做到安全的释放呢?
现在我的一个程序中包括20个线程,我必须做到每个线程都安全的释放
请大家帮忙,放分我从不吝啬:)
 
循环应该是 while not Terminateddo

或 while truedo
begin
if Terminated then
break;
end;

procedure TForm1.FormDestroy(Sender: TObject);
// Terminate any threads still running
begin
if (MyThread1 <> nil) and (Thread1Active = true) then
begin
MyThread1.Terminate;
MyThread1.WaitFor;
// wait for it to terminate
end;
if (MyThread2 <> nil) and (Thread2Active = true) then
begin
MyThread2.Terminate;
MyThread2.WaitFor;
end;
end;
 
while not terminateddo
begin
end;
程序关闭的时候把线程给terminal掉
 
public
{ Public declarations }
exitthread1,exitthread2,exitthread3...exitthread30:boolean;
... ...
exitthread1:=true;
... ...
(线程1循环中)
if exitthread1=ture then
exit;
 
首先问楼主一个问题,那就是你的线程里面是不是有一定时间间隔的?比如说1分钟重复一次操作这种?另外就是退出的时候,可以使用waitfor******这一系列的函数,而且很管用。
 
freeonterminate := true;
threadxxx.terminate;
 
不要随便就贴一个
freeonterminate := true;
threadxxx.terminate;
你知道上面这两句到底干了什么吗?
我告诉你,第一句只是在线程结束的时候,用户不用去管理创建的对象是不是已经释放了。
第二句,并没有真的结束一个线程,而只是将该线程的terminated设置为true。但是对于那些不断循环处理同样事件的线程,比如说是定时采集数据的线程,那么你要等很久才能结束,而且可能会出错。尤其是线程多的时候。我不知道为什么。
 
{ 2005-10-04 10:56 am by muhx }
procedure TSysInfo.FreeCmdThread(AFrmProgress: TFrmProgress);
var
i: Integer;
begin
for i := 0 to NUM_UNIT - 1do
begin
if FThreadArray = nil then
Continue;
if not FThreadArray.Suspended then
begin
FThreadArray.gReceiving := False;
FThreadArray.gPaused := True;
end;
end;
AFrmProgress.ShowProgress(20, HFreeThread);
Sleep(200);
for i := 0 to NUM_UNIT - 1do
if FThreadArray <> nil then
begin
FThreadArray.Terminate;
//Sleep(300);
FThreadArray.WaitFor;
AFrmProgress.ShowProgress(20 + i * 3, HFreeThread);
end;
end;

按照上面的朋友说的方法改成这样FThreadArray.WaitFor;会报错
请对线程有研究的朋友帮我想想办法,谢谢
 
首先waitfor是等待线程结束返回结束标志,waitfor最好用在onclosequery事件里面吧,还有就是如果你的整个系统退出的话,waitfor会等很长时间,另外,如果处理不好,会因为未完成资源的释放,而导致系统错误,这是多线程里面很棘手的问题。其实在多线程里面,考虑最多的也就是资源问题,资源的共享,互斥,以及资源的释放。
另外,你的循环没有循环完,在第一个waitfor的地方就卡住了,你用单步调试看看。
我的一个解决方案,就是使用waitforsingalobject这个系列的函数,保证可以圆满的解决你的问题。
 
有N种方法可以实现这个功能
如果在死循环中是每等一段时间后运行一些不会线程外部资源互相影响的操作的话
可以在每次等待完成后检测一个全局变量
如果在死循环内部还有和外部资源相互影响的代码
可以重载线程函数的BeforeDestruction函数
在这个函数内部构建释放线程数据的代码
然后在主线程退出时依次调用每个线程的Free方法
就可以了
因为每次调用Free都会让BeforeDestruction函数先运行,而不管线程是什么状态
 
请cqwty详细说一下,谢谢
 
好像下班了,人气不旺啊:)
 
按照cqwty说的使用WaitForSingleObject好像有点眉目了,请cqwty详细说明一下WaitForSingleObject怎样使用,实现什么功能,谢谢
 
在多线程的execute中写下如下的代码:
while not terminateddo
begin
if waitforsingalobject(....)==.... then
begin
处理你要处理的东西,不过我想你这个位置是退出。那就直接写一条语句break
end
else
begin
这个位置写你要处理的代码了。
end;
end;
说明一下,我对waitforsingalobject的使用不是记得很清楚了,参数也记不得了,但是需要一个事件,创建这个事件,然后才能使用的。你查一下吧。晚上如果还没有解决,我回到住的地方才能给你答复了。不好意思。
 
对了,你找一本delphi深度历险看看,在定时器那一章里面,这几个函数讲的很详细的。
 
谢谢楼上的朋友,我试试看
 
还没有解决,请给我一个判断线程是否结束的标志,谢谢
 
判断线程结束的标志很好给啊,你创建一个事件,然后setevent就可以了啊,这个不是就解决了吗?现在总结出来,你需要两个事件,一个是时间定时处理,一个是结束事件,对吧。当waitformultipleobjects等待到定时的事件,那就处理你要完成的功能,当等待到结束事件,那就break语句,跳出while not terminateddo
这个循环,然后准备释放你所创建的对象。这样能明白了吗?
 
某个线程程序:
unit Unit2;
interface
uses
Classes, SyncObjs;
type
Theard=class(TThread)
private
{ Private declarations }
protected
procedure Execute;
override;
end;
var
...
implementation
uses Unit1;
procedure Theard.Execute;
var
...
begin
while not Terminateddo
begin

//你的代码
end;

end;


procedure YourForm.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
YourEvent1.SetEvent;
YourEvent2.SetEvent;
... //为了避免出现异常现象,加上这几句
lsw.Terminate;
lsw.WaitFor;     //等待线程处理完程序后退出
FreeAndNil(Theard);
FreeAndNil(YourEvent1);
FreeAndNil(YourEvent2);//释放内存,避免内存泄露。
...
end;
 
后退
顶部