如何优雅地停止长时间执行线程?

时间:2008-10-31 23:51:50

标签: multithreading delphi

我有Delphi的线程问题。我想这在其他语言中也很常见。我有一个很长的过程,我在一个线程中,填充主窗口中的列表。但是如果某些参数在平均时间内发生变化,那么我应该停止当前正在执行的线程并从头开始。 Delphi建议通过设置Terminated:= true来终止线程,并在线程中检查此变量的值。但是我的问题是这个,长的执行部分被埋在库调用中,在这个调用中我无法检查Terminated变量。因此我不得不等待这个库调用完成,这会影响整个程序。

在这种情况下,首选的方法是什么?我可以立即杀死线程吗?

4 个答案:

答案 0 :(得分:9)

首选方法是修改代码,使其在不检查取消的情况下不会阻止。

由于您无法修改代码,因此无法执行此操作;你要么必须使用后台操作(但你可以将它与任何UI取消关联,以便它的完成将被忽略);或者,您可以尝试终止它(TerminateThread API将粗暴地终止给定其句柄的任何线程)。终止并不干净,但是,像Rob说的那样,线程所持有的任何锁都将被放弃,并且受此类锁保护的任何跨线程状态都可能处于损坏状态。

你能考虑在一个单独的可执行文件中调用该函数吗?也许使用RPC(管道,TCP,而不是共享内存,因为相同的锁定问题),以便您可以终止进程而不是终止线程?进程隔离将为您提供更好的保护。只要你不依赖于跨进程命名的东西,比如互斥,它应该比杀死一个线程更安全。

答案 1 :(得分:3)

线程需要合作才能实现正常关闭。我不确定Delphi是否提供了中止另一个线程的机制,但这种机制在.NET和Java中可用,但应该被认为是最后的选择,应用程序的状态在使用后是不确定的。 / p>

如果你可以在一个任意点杀死一个线程,那么你可以在它在内存分配器中持有一个锁时杀死它(例如)。当您的主线程接下来需要访问该锁时,这将使您的程序处于挂起状态。

答案 2 :(得分:3)

如果您无法修改代码以检查终止,那么只需将其优先级设置为非常低,并在返回时忽略它。

答案 3 :(得分:0)

我在回复similar question时写了这个:

  

我使用基于异常的技术   这对我来说非常好用   Win32应用程序的数量。

     

要终止线程,我使用   QueueUserAPC将呼叫排队到   抛出异常的函数。   然而,抛出的异常   不是从类型派生的   “例外”,所以只会被抓住   我的线程的包装程序。

我已经非常成功地将它用于C ++ Builder应用程序。我不知道Delphi与C ++异常处理的所有细微之处,但我希望它可以很容易地被修改为可以工作。