Как получить использование CPU на поток на окнах (win32)

Обновление Arkadiy: я наблюдал более корректное поведение System.currentTimeMillis() в Windows 7 в Oracle Java 8. Время было возвращено с 1 точностью миллисекунды. Исходный код в OpenJDK не изменился, таким образом, я не знаю то, что вызывает лучшее поведение.

David Holmes из Sun отправил статью блога пара несколько лет назад, которая имеет очень подробный взгляд на API синхронизации Java (в особенности System.currentTimeMillis() и System.nanoTime()), когда Вы хотели бы использовать, который, и как они работают внутренне.

Внутренняя часть Горячая точка VM: Часы, Таймеры и События Планирования - Первая часть - Windows

One, который очень интересный аспект таймера, используемого Java в Windows для API, которые имеют синхронизированный параметр ожидания, - то, что разрешение таймера может измениться в зависимости от того, чем другие вызовы API, возможно, были сделаны - в масштабе всей системы (не только в конкретном процессе). Он показывает пример, где использование Thread.sleep() вызовет это изменение разрешения.

19
задан Dirk Paessler 8 September 2009 в 09:40
поделиться

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;
6
ответ дан 30 November 2019 в 02:29
поделиться

Эти функции необходимо использовать для получения данных об использовании ЦП для каждого потока и процесса.

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

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

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

Вот отличная статья доктора Добба Параметры измерения производительности Win32

Пока.

23
ответ дан 30 November 2019 в 02:29
поделиться

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

Для Delphi доступна библиотека , которая предоставляет оболочки для большинства запросов WMI, однако потребуется некоторое экспериментирование, чтобы получить точный запрос, который вы ищете. Синтаксис запроса очень похож на sql, например, в моей системе для возврата процента процессорного времени для threadid 8, для процесса id 4:

10
ответ дан 30 November 2019 в 02:29
поделиться

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

4
ответ дан 30 November 2019 в 02:29
поделиться

Важно знать, что в определенных ситуациях время выполнения потока может быть бесполезным. Время выполнения каждого потока обновляется каждые 15 миллисекунд, как правило, для многоядерных систем, поэтому, если поток завершит свою задачу до этого времени, время выполнения будет сброшено. Более подробную информацию можно получить по ссылке: GetThreadTimes и результат меня удивил!
и Почему GetThreadTimes неверен

8
ответ дан 30 November 2019 в 02:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: