C++ 如何以编程方式获取Windows进程的线程数?

C++ 如何以编程方式获取Windows进程的线程数?,c++,windows,multithreading,C++,Windows,Multithreading,我想通过C/C++计算当前Windows进程的本机线程数。我看到有一个带有.NET答案的解决方案,但我不能使用该解决方案。我怀疑通过PdhOpenQuery/PdhCollectQueryData可能有一个解决方案,但我还没有探索这个方向,我希望有一个更简单的方法 更新:我应该说我当前的实现使用CreateToolhelp32Snapshot/Thread32First/Thread32Next,这正是我试图替换的。该实现非常繁重,在我的流程中每次调用都会导致20000页错误。也许我只是用错了

我想通过C/C++计算当前Windows进程的本机线程数。我看到有一个带有.NET答案的解决方案,但我不能使用该解决方案。我怀疑通过PdhOpenQuery/PdhCollectQueryData可能有一个解决方案,但我还没有探索这个方向,我希望有一个更简单的方法

更新:我应该说我当前的实现使用CreateToolhelp32Snapshot/Thread32First/Thread32Next,这正是我试图替换的。该实现非常繁重,在我的流程中每次调用都会导致20000页错误。也许我只是用错了


更新2:最适合我的解决方案是使用我感兴趣的进程的PID创建一个类似\Process\ux\Thread的字符串。然后我调用PdhExpandWildCardPath来扩展通配符。然后调用PdhOpenQuery、PdhAddCounter和PdhCollectQueryData进行初始化。此后,我调用PdhCollectQueryData和PdhGetFormattedCounterValue定期获取我的值。

工具帮助API提供了一组函数来枚举线程。使用Thread32First和Thread32Next可以计数。

工具帮助API提供了一组函数来枚举线程。使用Thread32First和Thread32Next可以进行计数。

编辑第二个:文本显示当前进程。如果确实是这样,您可以实现一个小DLL,它使用DLL\U thread\u DETACH上的InterlockedDecrement和DLL\U thread\u ATTACH上的InterlockedDecrement维护一个活动线程计数器

您必须确保进程尽早加载此DLL,以便主线程的线程计数从1开始。然后,线程数始终是最新的,并且可以通过联锁的*API快速访问

编辑:为了提高性能,您可以访问进程的PerfMon计数器,并一次性获得给定进程的线程数。有一个VB代码,你可以用它来建模

您也可以使用WMI按进程枚举线程,但这并不是一个简单的编程模型

PerfMon将是最快的

原件: 陈雷蒙对此有确切的指示。只需要在printf之前的条件下,通过匹配您自己获得的进程ID进行过滤


编辑第二条:文本显示当前进程。如果确实是这样,您可以实现一个小DLL,它使用DLL\U thread\u DETACH上的InterlockedDecrement和DLL\U thread\u ATTACH上的InterlockedDecrement维护一个活动线程计数器

您必须确保进程尽早加载此DLL,以便主线程的线程计数从1开始。然后,线程数始终是最新的,并且可以通过联锁的*API快速访问

编辑:为了提高性能,您可以访问进程的PerfMon计数器,并一次性获得给定进程的线程数。有一个VB代码,你可以用它来建模

您也可以使用WMI按进程枚举线程,但这并不是一个简单的编程模型

PerfMon将是最快的

原件: 陈雷蒙对此有确切的指示。只需要在printf之前的条件下,通过匹配您自己获得的进程ID进行过滤


谢谢,我刚刚更新了问题,以表明您的解决方案是我今天正在使用的,但我正在寻找性能更好的解决方案。或者我太担心这个解决方案的页面错误后果了?@Chris-see edit-Perfmon通常使用共享内存,这应该很快。Steve,谢谢你的DLL_线程_分离想法。这段代码必须作为JVM进程下的延迟加载DLL运行,这样就无法运行。我现在正在尝试PDH解决方案…谢谢,我刚刚更新了问题,以表明您的解决方案就是我目前使用的解决方案,但我正在寻找性能更高的解决方案。或者我太担心这个解决方案的页面错误后果了?@Chris-see edit-Perfmon通常使用共享内存,这应该很快。Steve,谢谢你的DLL_线程_分离想法。这段代码必须作为JVM进程下的延迟加载DLL运行,这样就无法运行。我正在尝试PDH解决方案。。。
#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>

int __cdecl main(int argc, char **argv)
{
 HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
 if (h != INVALID_HANDLE_VALUE) {
  THREADENTRY32 te;
  te.dwSize = sizeof(te);
  if (Thread32First(h, &te)) {
   do {
     if (te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) +
                      sizeof(te.th32OwnerProcessID)) {
       printf("Process 0x%04x Thread 0x%04x\n",
             te.th32OwnerProcessID, te.th32ThreadID);
     }
   te.dwSize = sizeof(te);
   } while (Thread32Next(h, &te));
  }
  CloseHandle(h);
 }
 return 0;
}