2009-09-08 2 views
18

Ищет функции API Win32, пример кода C++ или Delphi, который говорит мне о потреблении процессора (процентное и/или общее время процессора) потока (а не общее для процесс). У меня есть идентификатор потока.Как получить использование процессора в потоке на окнах (win32)

Я знаю, что Sysinternals Process Explorer может отображать эту информацию, но мне нужна эта информация внутри моей программы.

ответ

5

С помощью ответа RRUZ в выше, я, наконец, придумал этот код для Borland Delphi:

const 
    THREAD_TERMINATE     = $0001; 
    THREAD_SUSPEND_RESUME   = $0002; 
    THREAD_GET_CONTEXT    = $0008; 
    THREAD_SET_CONTEXT    = $0010; 
    THREAD_SET_INFORMATION   = $0020; 
    THREAD_QUERY_INFORMATION   = $0040; 
    THREAD_SET_THREAD_TOKEN   = $0080; 
    THREAD_IMPERSONATE    = $0100; 
    THREAD_DIRECT_IMPERSONATION  = $0200; 
    THREAD_SET_LIMITED_INFORMATION = $0400; 
    THREAD_QUERY_LIMITED_INFORMATION = $0800; 
    THREAD_ALL_ACCESS    = STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $03FF; 

function OpenThread(dwDesiredAccess: DWord; 
        bInheritHandle: Bool; 
        dwThreadId: DWord): DWord; stdcall; external 'kernel32.dll'; 


procedure TForm1.Button1Click(Sender: TObject); 
var iii:integer; 
    handle:thandle; 
    creationtime,exittime,kerneltime,usertime:filetime; 
begin 
    Handle:=OpenThread(THREAD_SET_INFORMATION or THREAD_QUERY_INFORMATION, False, windows.GetCurrentThreadId); 
    if handle<>0 then 
    begin 
    getthreadtimes(Handle,creationtime,exittime,kerneltime,usertime); 
    label1.caption:='Total time for Thread #'+inttostr(windows.GetCurrentThreadId)+': '+inttostr((int64(kerneltime)+int64(usertime)) div 1000)+' msec'; 
    CloseHandle(Handle); 
    end; 
end; 
+0

Но это дает вам время, затрачиваемое на поток, а не процент использования ЦП. Вы также можете получить общее время от вызовов WMI вместе с процентом в одном запросе. – skamradt

+0

Я думаю, вы можете сделать вывод о количестве использования процессора, опросив каждую секунду, и если его «kernel + usertime» увеличивается на 1.0, что означает, что он использовал 100% одного ядра для этой секунды, да? – rogerdpack

3

Использование функции "GetThreadTimes"? Если вы измеряете время между вызовами на «GetThreadTimes» и сохраняете предыдущее время пользователя и/или ядра, тогда вы знаете, сколько времени было у потока с момента последнего обновления. Вы также знаете, сколько времени прошло в среднем, и, таким образом, вы можете определить, сколько процессорного времени было использовано. Было бы лучше (по причинам разрешения таймера) сделать эту проверку каждую секунду или около того и выработать свое среднее использование ЦП за эту секунду.

20

Вы должны использовать эти функции для получения использования процессора в потоке и процессе.

GetThreadTimes (извлекает информацию для указанного потока синхронизации.)

GetProcessTimes (извлекает информацию для указанного процесса синхронизации.)

GetSystemTime (извлекает текущую дату и время системы. Системное время выражается в Универсальное координированное время UTC)

Вот отличная статья от доктора Добба Win32 Performance Measurement Options

Пока.

+0

Также прочитайте ответ lsalamon, чтобы отметить, что GetThreadTimes может быть «менее точным» – rogerdpack

9

Данные, на которые вы ссылаетесь, доступны с использованием специальных вызовов WMI. Вы можете запросить Win32_Process, чтобы получить всю информацию о конкретном процессе, и запросить Win32_PerfFormattedData_PerfProc_Process, чтобы получить количество потоков, и заданный дескриптор потока (что я считаю вашим поиском) вы можете запросить Win32_PerfRawData_PerfProc_Thread, чтобы получить процент используемого времени процессора.

Существует library available for Delphi, который предоставляет обертки для большинства запросов WMI, однако для получения точного запроса вам потребуется некоторое экспериментирование. Синтаксис запросов очень SQL, как, например, на моей системе, чтобы вернуть процент процессорного времени для ThreadId 8, идентификатор процесса 4 является:

SELECT PercentProcessorTime FROM Win32_PerfRawData_PerfProc_Thread 
    WHERE IdProcess=4 and IdThread=8 

Большинство программ, которые присутствуют статистические данные о запущенных процессах в настоящее время используют WMI для запроса этой информации.

6

Важно знать, что в определенных ситуациях, время выполнения нити может быть бесполезной. Время выполнения каждого потока обновляется каждые 15 миллисекунд, как правило, для многоядерных систем, поэтому, если поток завершает свою задачу до этого времени, среда выполнения будет сброшена. Более подробную информацию можно получить по ссылке: GetThreadTimes function and I was surprised by the result!
и Why GetThreadTimes is wrong

+3

Видимо, в Vista + вы можете вызвать QueryThreadCycleTime для большей точности. http://stackoverflow.com/questions/5532046/c-getthreadtimes-but-with-a-better-resolution. Я предполагаю, что с Vista + GetThreadTimes также более точным, но TBD. – rogerdpack

0

Here простой WMI обертка запрос.С помощью него вы можете вызвать это, чтобы получить данные:

getWmiQueryResult(L"SELECT PercentProcessorTime FROM Win32_PerfRawData_PerfProc_Thread WHERE IdProcess=4 and IdThread=8", L"PercentProcessorTime "); 

Кроме того, вы можете захотеть взглянуть на документацию Win32_PerfRawData_PerfProc_Thread, чтобы посмотреть, что другие свойства вы можете получить.

Смежные вопросы