Как программно получить количество потоков для процесса Windows?

Я хочу посчитать собственные потоки текущего процесса Windows через C/C++. Я вижу, что есть связанный вопрос с ответом.NET, но я не могу использовать это решение. Я подозреваю, что может быть решение через PdhOpenQuery / PdhCollectQueryData, но я еще не исследовал это направление, и я надеюсь, что есть более простой подход.

ОБНОВЛЕНИЕ: я должен был сказать, что моя текущая реализация использует CreateToolhelp32Snapshot/Thread32First/Thread32Next, и это то, что я пытаюсь заменить. Эта реализация сложна и вызывает 20000 сбоев страниц при каждом вызове в моем процессе. Может я просто неправильно его использую?

Обновление 2: Лучшим решением для меня было создать строку типа "\ Process (_) \ Thread Count" с PID интересующего меня процесса. Затем я вызвал PdhExpandWildCardPath (), чтобы развернуть подстановочный знак " ". Затем я вызвал PdhOpenQuery (), PdhAddCounter () и PdhCollectQueryData() для инициализации. После этого я вызывал PdhCollectQueryData() и PdhGetFormattedCounterValue (), чтобы периодически получать мои значения.

2 ответа

Решение

РЕДАКТИРОВАТЬ второе: ваш текст говорит "текущий процесс". Если это действительно так, вы могли бы реализовать небольшую DLL, чья DllMain поддерживает счетчик активных потоков, используя InterlockedDecrement (на DLL_THREAD_DETACH) а также InterlockedIncrement (на DLL_THREAD_ATTACH).

Вы должны были бы убедиться, что ваш процесс загружает эту DLL на ранней стадии, чтобы счетчик потоков начинался с 1 для нашего основного потока. Тогда ваш счет потока всегда актуален и быстро доступен через Interlocked* API-интерфейсы.

РЕДАКТИРОВАТЬ: для повышения производительности, вы можете получить доступ к счетчикам PerfMon для вашего процесса и получить счетчик потоков для данного процесса за один выстрел. Здесь есть VB-код, который можно смоделировать.

Вы также можете использовать WMI для перечисления потоков по процессам, но это вряд ли простая модель программирования.

PerfMon будет самым быстрым.

ОРИГИНАЛ: У Раймонда Чена есть точные инструкции для этого здесь. Просто нужно отфильтровать по идентификатору процесса, совпадающему с вашим собственным (полученным через 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;
}

ToolHelp API предоставляет набор функций для перечисления потоков. С помощью Thread32First а также Thread32Next ты можешь посчитать.

Другие вопросы по тегам