代码之家  ›  专栏  ›  技术社区  ›  Chris Dolan

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

  •  1
  • Chris Dolan  · 技术社区  · 15 年前

    我想通过C/C++对当前Windows进程的本地线程进行计数。我看到有一个 related question 有.NET的答案,但我不能使用那个解决方案。我怀疑通过pdhopenquery/pdhcollectquerydata可能有一个解决方案,但我还没有探索这个方向,我希望有一个更简单的方法。

    更新:我应该说我当前的实现使用了createToolHelp32Snapshot/thread32first/thread32next,这就是我要替换的内容。这个实现非常复杂,在我的过程中每次调用都会导致20000个页面错误。也许我用错了?

    更新2:最适合我的解决方案是创建一个类似字符串的\进程( _“线程计数”和我感兴趣的进程的PID。然后我调用pdhexPandWildcardPath()来扩展 “通配符。然后我调用pdhopenquery()、pdhadcounter()和pdhcollectquerydata()初始化。此后,我调用pdhcollectquerydata()和pdhgetFormattedCounterValue()定期获取我的值。

    2 回复  |  直到 15 年前
        1
  •  2
  •   Steve Townsend    15 年前

    编辑第二个:文本显示“当前进程”。如果真是这样,您可以实现一个小的dll DllMain 使用维护活动线程计数器 InterlockedDecrement (上) DLL_THREAD_DETACH ) InterlockedIncrement (上) DLL_THREAD_ATTACH )

    您必须确保您的进程尽早加载这个DLL,以便主线程的线程计数从1开始。然后,您的线程计数始终是最新的,并且可以通过 Interlocked* API。

    编辑:为了提高性能,可以访问进程的性能计数器,并一次性获取给定进程的线程计数。有VB代码 here 你可以模仿的。

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

    Perfmon将是最快的。

    原件: 陈瑞蒙对此有确切指示 here . 只需按与您自己的进程ID匹配的进程ID进行筛选(通过 GetCurrentProcessId )在之前的情况下 printf

    #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;
    }
    
        2
  •  1
  •   harper    15 年前

    toolhelp api提供一组函数来枚举线程。使用 Thread32First Thread32Next 你可以数数。