所以。为了上下文。我有一个程序,它有多个线程读取传感器数据(使用来自 dll 的 Funktion)并将它们推送到缓冲区。问题是线程在 sleep_until 之间睡眠不同的时间间隔。可以是 5 分钟甚至更长。这意味着,如果我尝试关闭程序并等待连接,我将不得不等到所有线程唤醒并注意到它们可以停止。
现在我的问题:用 TerminateThread 强制关闭它们可以吗,因为程序无论如何都会退出并释放所有资源?
试过了,好像有效。我不确定我是否造成了我没有注意到的问题。
TerminateThread
文档的“备注”部分,并注意其中关于执行此操作的各种危险的明确程度。
在撰写本文时,该部分内容如下:
用于导致线程退出。当这种情况发生时, 目标线程没有机会执行任何用户模式代码。 DLL 附加到线程时不会通知该线程 终止。系统释放线程的初始堆栈。TerminateThread
Windows Server 2003 和 Windows XP: 目标线程的初始堆栈 没有被释放,导致资源泄漏。
是一个危险的函数,只能在以下情况下使用 最极端的情况。仅当您 确切地知道目标线程正在做什么,并且您可以控制所有 目标线程当时可能正在运行的代码 的终止。例如,TerminateThread
可能会导致 以下问题: 如果目标线程拥有临界区,则该临界区不会被释放。TerminateThread
- 如果目标线程正在从堆中分配内存,则堆锁不会被释放。
- 如果目标线程在终止时正在执行某些 kernel32 调用,则该线程进程的 kernel32 状态可能是 不一致。
- 如果目标线程正在操作共享 DLL 的全局状态,则 DLL 的状态可能会被破坏,从而影响其他用户 DLL。
- 除了控制对其句柄的访问之外,线程无法保护自己免受
TerminateThread
的侵害。
和TerminateThread
函数返回的线程句柄具有CreateThread
访问权限,因此任何持有这些句柄之一的调用者都可以终止您的线程。如果目标线程是进程的最后一个线程,则此时 函数被调用,线程的进程也被终止。CreateProcess
线程对象的状态变为有信号状态,释放任何其他对象 一直在等待线程终止的线程。这 线程的终止状态从
THREAD_TERMINATE
更改为 dwExitCode 参数。
终止线程并不一定会删除线程对象 从系统中。当最后一个线程结束时,线程对象被删除 手柄已关闭。这一切听起来都很可怕!但你能做什么呢?
在 Windows 中实现您想要的目标的一种更简洁的方法是设置一个
event,当发出信号时将导致所有线程退出。 您可以使用
创建一个事件,并将该句柄传递给所有线程。每当线程想要执行睡眠时,它可以使用
CreateEvent
(或
WaitForSingleObject
)并设置超时。当应用程序退出时,您可以通过 发出事件信号。这将唤醒所有休眠线程,如果 wait 调用的返回值是
SetEvent
(或在等待多个对象时类似),那么它们就知道是时候清理并退出了。完成后他们应该打电话给 WAIT_OBJECT_0
。在主程序端,发出信号后,您将使用带有
ExitThread
的循环来等待所有线程完成。可以在这里使用超时来掩盖异常情况,然后显式终止任何无法正常退出的线程。
假设您的线程是使用创建的,则主清理中要做的最后一件事是在所有句柄上调用
CreateThread
,即使您在该句柄上调用
CloseHandle
。