Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 在未终止的情况下,是否仍无法退出线程?_Delphi - Fatal编程技术网

Delphi 在未终止的情况下,是否仍无法退出线程?

Delphi 在未终止的情况下,是否仍无法退出线程?,delphi,Delphi,昨天,专家建议在ThreadExecute函数中使用“whilenotterminated do begin…”来检查线程终止属性,并从内部优雅地退出线程。我们刚刚测试了代码,但它仍然不能终止线程。但是,通过外部调用TerminateThread函数,可以实际地立即终止该线程。execute函数或execute函数中的大while循环有缺陷吗?或者在使用非端接回路时是否有特殊要求 顺便问一下,endthread、exitthread和terminatethread之间有什么区别?如何使用它们?哪

昨天,专家建议在ThreadExecute函数中使用“whilenotterminated do begin…”来检查线程终止属性,并从内部优雅地退出线程。我们刚刚测试了代码,但它仍然不能终止线程。但是,通过外部调用TerminateThread函数,可以实际地立即终止该线程。execute函数或execute函数中的大while循环有缺陷吗?或者在使用非端接回路时是否有特殊要求

顺便问一下,endthread、exitthread和terminatethread之间有什么区别?如何使用它们?哪个比较好


再次感谢您的帮助。

如果
未终止时do
没有足够快地终止线程,则每次迭代中完成的工作太多(即,很少检查循环条件
未终止
),或者您“意外”在该循环后放置了大量代码

当然,如果有一个线程反复运行循环,直到终止,那么应该执行
,而不执行
。通常一次迭代在短时间内完成(以每秒1到10000次迭代的顺序?),因此经常检查循环条件(每秒1到10000次)。但是如果您的线程不包含这样的循环,那么,当然,将整个
Execute
主体放在
中而不终止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;
坏的

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;

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

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

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

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

do while not terminating:
    wait 2 seconds for work
    if not terminating and work available:
        do it
一旦设置了
终止
标志,该特定线程退出的时间将不会超过两秒钟


<>和,如果<代码>做它是一个长时间运行的任务,你也可能要定期检查,如果你也应该退出的话。

< P>如果你<强> >必须/<强>终止作业——因为它在你无法控制的代码中被阻塞,例如,然后考虑尝试把它包在一个单独的可执行文件中,并将其作为子进程运行,并在需要停止时终止该进程。进程的隔离性比线程强得多。终止一个线程肯定会带来痛苦——如果被终止的线程在内存管理器或类似的地方持有一个锁怎么办?下次你尝试分配内存(或类似的内存)时,你的应用程序就会死锁

永远不要从外面杀死一根线。它使应用程序处于未定义的状态。很可能您的线程正在等待事件或类似事件。使用调试器了解它正在做什么。还值得一提的是TThread.Waitfor,它允许您确保在释放线程之前停止线程。TerminateThread应该被重命名为RandomlyDeadLockMyProcessAndOccasionalyCorruptMyMemory。我期待在下一版本的Delphi中使用新的命名:)