给定一个线程 id,如何确定它是不是仍在 Windows 上运行

Posted

技术标签:

【中文标题】给定一个线程 id,如何确定它是不是仍在 Windows 上运行【英文标题】:Given a thread id, how to decide it's still running or not on Windows给定一个线程 id,如何确定它是否仍在 Windows 上运行 【发布时间】:2011-11-14 19:20:40 【问题描述】:

在 linux 上,我们有 pthread_kill() 来执行此操作。我正在尝试为它找到一个 Windows 对应项。

换句话说,给定一个线程id,有没有办法判断线程是否还在运行?

GetExitCodeThread() 是我找到的最接近的,但是,它需要线程句柄而不是线程 ID 作为其参数。

【问题讨论】:

我相信pthread_kill() 具有与您的答案中描述的相同的缺点。您是在控制这个线程的生命周期,还是只是一些随机线程? @DavidHeffernan 你的意思是我们仍然要承担 linux 上的 id 回收所带来的风险? 我不相信你可以跨进程边界使用 POSIX 线程标识符,所以这个警告可能只适用于 windows。 是的,我想是这样的。我希望两个系统都采取措施使回收冲突不太可能发生,但两者都必须是可能的。 @Terry 线程从何而来?它们在你的控制之下吗? 【参考方案1】:

您不应该为此使用线程 id:线程 id 可以重复使用,因此如果您获得了线程 id,则该线程退出,另一个线程可以使用相同的线程 id 启动。

句柄不存在这个问题:一旦线程终止,该线程的所有句柄都会反映线程的终止状态。

您可以使用OpenThread 获取具有给定ID 的线程的句柄;然后您可以将该句柄传递给GetExitCodeThread 以确定线程是否已退出。

【讨论】:

我刚刚咨询了我的经理。他们坚持不仅可以重用 id,而且可以重用句柄(本质上是内存地址)。因此,在他们看来,使用其中一种几乎没有什么区别。在实践中,他们根据 20 年的经验得出结论,很少观察到重复使用相同的 ID。 您的管理者错了:如果您打开一个线程的句柄,该句柄将始终引用该线程,直到您关闭该句柄,即使线程终止。线程 id 重用是否频繁发生,这无关紧要:正确的程序不能假设特定线程 id 总是引用同一个线程,除非它有一些其他的知道方式(例如,如果你有一个线程得到它自己的 id ,只要它在运行,它就可以知道该 id 是有效的——线程 id 不会改变)。【参考方案2】:

简而言之,不,没有。您可以确定具有给定标识符的线程是否存在。但是,您根本无法确定您使用给定 ID 引用的线程是否仍在运行。那是因为线程ID会在线程完成后被回收。

要跟踪线程的生命周期,您需要获取线程句柄,这将允许您在需要时保持线程处于活动状态。把它想象成一个强大的VS。弱参考的东西。您可以使用OpenThread() 获取给定线程 ID 的线程句柄。您应该在获得 ID 后尽快执行此操作,然后始终使用线程句柄。

【讨论】:

你的意思是ID给了我们句柄,而句柄又给了我们运行状态?如果是这样,我们可以从 ID 中获取运行状态。 是的,但这是一种不可靠的方法,因为您不确定要测试的哪个线程的状态。如果感兴趣的线程完成并且所有句柄都关闭,那么任何其他进程都可以创建一个可能使用该标识符的线程。如果在此之后执行您的测试,那么您将得到误报。 我刚刚咨询了我的经理。他们坚持不仅可以重用 id,而且可以重用句柄(本质上是内存地址)。因此,在他们看来,使用其中一种几乎没有什么区别。在实践中,他们根据他们 20 年的经验得出结论,很少观察到重复使用相同的 ID。 @TerryLiYifeng:句柄可以重复使用,但在你持有对它们的引用时不能。持有一个线程 ID 不会给出这样的承诺。将句柄视为强引用(使对象保持活动状态),将 ID 视为弱引用(如果释放所有强引用,则隐式无效)。这就是为什么我指出你应该尽快得到一个句柄并让它保持活力,直到你不再需要它为止。 至于二十年经验的事情,我不得不警告你,这是一个糟糕的论点。仅仅因为到目前为止你还没有看到一个错误爬到你身上,这并不意味着它不存在。此外,如果您可以证明 ID 的保存期限比线程本身短,那么保留 ID 是有效的。这对于一些只控制自己线程的程序是可以证明的。

以上是关于给定一个线程 id,如何确定它是不是仍在 Windows 上运行的主要内容,如果未能解决你的问题,请参考以下文章

如何轮询 iOS 应用程序并检查它是不是已退出活动?

如何确定一个实体是不是适合 O(N^2) 中的给定框?

如何知道其他线程是不是已经完成?

在 Java 中,如何确定线程是不是正在运行?

检测进程是不是仍在运行

当 std::lock_guard 仍在范围内时,使用 pthread_create 创建线程是不是安全?