如何正确确定进程的主(第一个)线程[已关闭]

问题描述 投票:0回答:1

关于如何识别进程的主线程,存在很多疑问。一个常见的答案是没有“主”线程,所有线程都是等效的。

这是一个不正确且高度理论化的答案。主线程是进程创建的第一个线程。 “线程”窗口中的 Visual Studio 调试器可以以某种方式将主线程与其他线程区分开来。我想知道,在加载静态链接的 DLL 时(在 WinMain 之前),调试器是如何执行的。最终,我想得到这个线程的ID。

编辑:正如@IInspectable所说,“虽然有一个线程最终初始化一个进程,但该线程没有任何显着特征。它可以在任何时候终止,而该进程拥有的其他线程继续执行”。我知道这一点并且完全同意。但我正在处理一个已有 30 年历史的巨大产品,由几个交互的 EXE 和数百个 DLL 组成。许多不同的 DLL(它们彼此之间以及 EXE 都一无所知)都有一些只允许在主线程上运行的代码。否则应用程序会崩溃。你可以多次重复说这是一个非常糟糕的设计,但这就是我所拥有的,我对此无能为力。这就是我所说的“实践”,与抽象真实但无用的陈述相反。

因此,我们的产品需要一种服务来告诉当前线程是否是进程的主线程。因此,我选择了一个非常基本的 DLL,它静态链接到所有 EXE 和几乎所有其他 DLL,并在那里实现了这样一个“服务”,正如 @MSalters 答案中所描述的那样。

这种方法一直运行良好,直到最近我开始收到来自另一个国家办事处的开发人员的投诉,称所选的 DLL 正在工作线程上加载(导致应用程序崩溃)。我们无法在办公室重现这种现象,因此我所拥有的只是调试器线程窗口的快照。以下是其中之一;如果它告诉某人一些事情,我会很高兴知道。

enter image description here

windows multithreading winapi win32-process
1个回答
1
投票

调试器可以显示哪个线程(如果有)源自 EXE 的入口点。这个入口点不是WinMain

,因为你的编译器需要入口点来设置它的运行时。该运行时调用您的 
WinMain

在DLL加载时(即

DllMain

你的代码在Loader Lock下运行,此时你几乎无能为力。但是对 DLL_PROCESS_ATTACH
 的调用专门发生在第一个线程上。因此,您无需执行任何操作即可找到该线程。您可以安全地使用 
TlsAlloc
 标记此线程以供将来使用。您也可以安全地调用 
GetCurrentThreadId
,因为这是一个 
kernel32
 函数,它已经在 
DllMain
 之前加载了。

© www.soinside.com 2019 - 2024. All rights reserved.