虽然没有终止,阻止仍然无法退出线程?

时间:2010-10-29 12:03:51

标签: delphi

昨天专家建议在线程执行函数中使用“while not ended do begin ...”来检查线程终止属性并从内部优雅地退出线程。我们刚刚测试了代码,但它仍然无法终止线程。但是这个线程可以通过外部调用TerminateThread函数实际终止。执行函数或执行函数中的大循环中有一些缺陷吗?或者在使用未终止循环时是否有特殊要求?

顺便说一句,endthread,exitthread和terminatethread之间有什么区别?怎么用?哪个比较好?

再次感谢你的帮助。

3 个答案:

答案 0 :(得分:9)

如果while not Terminated do没有足够快地终止线程,那么每次迭代完成的工作太多了(也就是说,很少检查循环条件not Terminated),或者你有“意外地“在这个循环之后放了很多代码

当然,如果你有一个反复运行循环的线程,直到终止,那么你应该while not Terminated do。通常,一次迭代在短时间内完成(按每秒1到10000次迭代的顺序?),因此经常检查循环条件(每秒1到10000次)。但是如果你的线程不包含这样的循环,那么当然,将整个Execute主体放在while not Terminated do内对你没用。

不可

procedure TMyThread.Execute;
begin
  inherited;
    while not Terminated do
      ComputeTheNextTenDigitsOfPi; // Takes 100 ms.
end;

<强>为

procedure TMyThread.Execute;
begin
  inherited;
    while not Terminated do
      ComputeAVeryVeryLargeFractal; // Takes an hour.
                                    // And you will create the same fractal
                                    // over and over again.
end;

答案 1 :(得分:8)

如果您必须终止作业 - 例如,因为它在您无法控制的代码中被阻止 - 那么考虑尝试将其完全包装在一个单独的可执行文件中,并将其作为一个单独的可执行文件运行子流程,并在需要停止时终止流程。进程具有比线程更强的隔离。终止一个线程是一个肯定的痛苦方法 - 如果被终止的线程在内存管理器或某个类似的地方持有锁定怎么办?下次尝试分配内存(或类似内存)时,您的应用程序将陷入僵局!

答案 2 :(得分:5)

CodeInChaos在评论中提供了一些很好的建议 - 在极少数情况下,线程应该从外部终止。

某些线程环境具有取消功能,您可以在其中取消(而不是终止)某个线程,并且在准备好时自行终止。这允许线程为何时安全终止设置自己的规则。

外部查杀的问题是目标线程可能具有资源锁定,现在永远不会释放,从而导致潜在的死锁。或者,即使在线程退出时释放资源,该资源中的数据也可能不再一致。

遵循的基本规则是所有线程必须检查是否应及时终止它们。换句话说,如果您正在等待工作,请在循环中经过几秒钟后超时并检查状态:

do while not terminating:
    wait 2 seconds for work
    if not terminating and work available:
        do it

设置terminating标志后,该特定线程永远不会超过约两秒钟退出。

并且,如果do it是一个长期运行的任务,您可能还想定期检查,如果您也应该退出。