delphi 没有handle时如何强行终止线程?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了delphi 没有handle时如何强行终止线程?相关的知识,希望对你有一定的参考价值。

参考技术A 你应该在创建线程对象时把它保存在一个变量(或列表变量)中,否则就找不到它了.FVThread
TVThread.Create(Name);
FVThread
OnTerminate
VThreadDone;此外,线程自己可以得到自己的Handle:OpenThread(THREAD_TERMINATE,False,GetCurrentThread);

如何终止 QThread

【中文标题】如何终止 QThread【英文标题】:How can I terminate a QThread 【发布时间】:2010-12-26 07:10:51 【问题描述】:

最近,我在这个标题中提到了这个问题。 我尝试过使用 QThread::terminate(),但我无法停止 处于死循环中的线程(比如说,while(1))。

非常感谢。

【问题讨论】:

重新标记以添加更常见的“qt”标签。 Qt 文档说:“警告:这个函数很危险,不鼓励使用。线程可以在其代码路径中的任何位置终止。线程可以在修改数据时终止。没有线程有机会自行清理,解锁任何持有的互斥锁等。简而言之,仅在绝对必要时使用此函数。可以通过调用 QThread::setTerminationEnabled() 显式启用或禁用终止。在禁用终止时调用此函数导致终止被推迟,直到重新启用终止。" 【参考方案1】:

你试过exit或quit吗?

【讨论】:

QT 帮助文档中的引用:“如果线程没有事件循环,这个函数什么都不做” 在事件循环的情况下它可能会起作用。但是如果我想在线程完成它的工作之前终止它,我应该怎么做?多谢。亲爱的。 事实上,这两个函数实际上是用于在调用 exec 时从事件循环中返回。【参考方案2】:

线程调用QThread::setTerminationEnabled(false)了吗?这将导致线程终止无限期延迟。

编辑:我不知道你在哪个平台上,但我检查了 QThread::terminate 的 Windows 实现。假设线程实际上开始运行,并且没有通过上述函数禁用终止,它基本上是 Windows API 中 TerminateThread() 的包装器。此函数接受任何线程的不尊重,并且往往会留下资源泄漏和类似悬空状态的混乱。如果它没有杀死线程,那么您要么正在处理僵尸内核调用(很可能是阻塞的 I/O),要么在某个地方遇到了更大的问题。

【讨论】:

我让它调用 setTerminationEnabled(true);【参考方案3】:

终止线程是停止异步操作的简单解决方案,但这通常是一个坏主意:线程可能正在执行系统调用,或者在终止时可能正在更新数据结构,这可能让程序甚至操作系统处于不稳定状态。

尝试将您的 while(1) 转换为 while(isAlive()) 并在您希望线程退出时使 isAlive() 返回 false。

【讨论】:

嗨,rpg。 while(1) 的例子只是一种情况。我真正想要的是终止正在执行大量计算且将持续很长时间的线程。我只想在它完成执行之前停止它。谢谢。 ps:我看到了Rocknroll给出的线索--use pipe to stop a Qthread。但是我从来没有找到解决方案。 尝试在繁重的计算函数中添加类似于中断点的内容:justsoftwaresolutions.co.uk/threading/… 是的,我同意这里所说的。以硬方式终止线程绝不是一件好事。【参考方案4】:

使用未命名的管道

int gPipeFdTest[2];  //create a global integer array

当您打算创建管道时使用

if( pipe(gPipeFdTest) < 0)



perror("Pipe failed");

exit(1);


上面的代码将创建一个管道,它有两端 gPipeFdTest[0] 用于读取和 gPipeFdTest[1] 用于写入。您可以做的是在您的运行函数中设置为使用 select 系统调用读取管道。并且从你想跑出来的地方,那里设置写使用写系统调用。我已经使用 select 系统调用来监视管道的读取端,因为它适合我的实现。试着在你的情况下弄清楚这一切。如果您需要更多帮助,请给我留言。

编辑:

我的问题和你的一样。我有一个 while(1) 循环,而我尝试的其他事情需要互斥锁和其他花哨的多线程 mumbo jumbo,这增加了复杂性,调试是一场噩梦。除了简化代码之外,使用管道使我摆脱了这些复杂性。我并不是说这是最好的选择,但在我的情况下,它被证明是最好和最干净的选择。在这个解决方案之前,我被挂起的应用程序窃听了。

【讨论】:

【参考方案5】:

如果 QThread 在终止期间“自然”完成,它们可能会死锁。

例如在 Unix 中,如果线程正在等待“读取”调用,则终止尝试(Unix 信号)将使“读取”调用在线程被销毁之前以错误代码中止。

这意味着线程在被终止时仍然可以到达它的自然退出点。当它这样做时,会发生死锁,因为某些内部互斥体已经被“终止”调用锁定。

我的解决方法是确保线程永远不会在被终止时返回。

while( read(...) > 0 ) 

  // Do stuff...


while( wasTerminated )
  sleep(1);

return;

wasTerminated 这里的实现其实有点复杂,使用原子整数:

enum 

  Running, Terminating, Quitting
;

QAtomicInt _state; // Initialized to Running

void myTerminate()

  if( _state.testAndSetAquire(Running, Terminating) )
    terminate();


void run()

  [...]

  while(read(...) > 0 ) 

    [...]
  

  if( !_state.testAndSetAquire(Running, Quitting) ) 
    for(;;) sleep(1);
  

【讨论】:

以上是关于delphi 没有handle时如何强行终止线程?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法强行杀死python中的线程?

如何停止线程?

有关delphi程序的问题

delphi 在线程A中终止线程B

delphi程序运行时别的功能无法使用

多线程 Delphi 7 App - 应用程序终止问题