Как программно получить количество потоков для процесса 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
ты можешь посчитать.