Временные характеристики процесса

Воспользовавшись функцией GetProcessTimes, которая в Windows 9x отсутствует, можно получить различные временные характеристики процесса, а именно: истекшее время (elapsed time), время, затраченное ядром (kernel time), и пользовательское время (user time).

BOOL GetProcessTimes(HANDLE hProcess, LPFILETIME lpCreationTime, LPFILETIME lpExitTime, LPFILETIME lpKernelTime, LPFILETIME lpUserTime)

Дескриптор процесса может ссылаться как на процесс, который продолжает выполняться, так и на процесс, выполнение которого прекратилось. Вычитая время создания процесса (creation time) из времени завершения процесса (exit time), мы получаем истекшее время, как показано в следующем примере. Тип данных FILETIME является 64-битовым; для вычисления указанной разности объедините переменную этого типа с переменной тип LARGE_INTEGER в структуру типа union. Ранее преобразование и отображение отметок времени файлов было продемонстрировано в главе 3 на примере программы lsw.

Функция GetThreadTimes аналогична только что описанной, но требует указания дескриптора потока в качестве параметра. Управлению потоками посвящена глава 7.

Пример: временные характеристики процессов

Наш следующий пример (программа 6.2) представляет собой команду timep (от time print — вывод временных параметров), аналогичную UNIX-команде time (поскольку команда time поддерживается процессором командной строки, мы должны использовать для нашей команды другое имя). Программа позволяет вывести все три временные характеристики, однако в Windows 9x будет доступно лишь истекшее время процесса.

Одним из возможных применений этой команды является сравнительный анализ времени выполнения и эффективности различных версий функций копирования и преобразования файлов из ASCII в Unicode, реализованных в предыдущих главах.

В данной программе используется функция Windows GetCommandLine, которая возвращает целую командную строку, а не отдельные строки из массива argv.

Кроме того, программа использует вспомогательную функцию SkipArg, которая просматривает командную строку и устанавливает в ней указатель в позицию, непосредственно следующую за именем исполняемого файла. Листинг функции SkipArg приведен в приложении А.

Для определения версии ОС в программе 6.2 используется функция GetVer-sionEx. В операционных системах Windows 9x и Windows СЕ доступным будет лишь истекшее время процесса. Программный код для этих систем представлен с той целью, чтобы показать, что в некоторых случаях работоспособность программ, по крайней мере — с частичным сохранением их функциональности, удается обеспечивать для целого диапазона различных версий Windows.

Программа 6.2. timep: временные характеристики процессов

/* Глава 6. timep. */

#include "EvryThng.h"

 

int _tmain(int argc, LPTSTR argv[]) {

STARTUPINFO Startup;

PROCESS_INFORMATION ProcInfo;

union { /* Эта структура используется для выполнения арифметических операций с участием временных параметров. */

LONGLONG li;

FILETIME ft;

} CreateTime, ExitTime, ElapsedTime;

FILETIME KernelTime, UserTime;

SYSTEMTIME ElTiSys, KeTiSys, UsTiSys, StartTimeSys, ExitTimeSys;

LPTSTR targv = SkipArg(GetCommandLine());

OSVERSIONINFO OSVer;

BOOL IsNT;

HANDLE hProc;

OSVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

GetVersionEx(&OSVer);

IsNT = (OSVer.dwPlatformId == VER_PLATFORM_WIN32_NT);

/* NT (все версии) возвращает VER_PLATFORM_WIN32_NT. */

GetStartupInfo(&StartUp);

GetSystemTime(&StartTimeSys);

/* Выполнить командную строку; дождаться завершения процесса. */

CreateProcess (NULL, targv, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &StartUp, &ProcInfo);

/* Убедиться в наличии ВСЕХ НЕОБХОДИМЫХ прав доступа к процессу. */

DuplicateHandle(GetCurrentProcess(), ProcInfo.hProcess, GetCurrentProcess(), &hProc, PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, 0);

WaitForSingleObject(hProc, INFINITE);

GetSystemTime (&ExitTimeSys);

if (IsNT) { /* Windows NT. Для процесса вычисляется истекшее время, время выполнения в режиме ядра и время выполнения в пользовательском режиме. */

GetProcessTimes(hProc, &CreateTime.ft, &ExitTime.ft, &KernelTime, &UserTime);

ElapsedTime.li = ExitTime.li – CreateTime.li;

FileTimeToSystemTime(&ElapsedTime.ft, &ElTiSys);

FileTimeToSystemTime(&KernelTime, &KeTiSys);

FileTimeToSystemTime(&UserTime, &UsTiSys);

_tprintf(_T("Истекшее время: %02d:%02d:%02d:%03d\n"), ElTiSys.wHour, ElTiSys.wMinute, ElTiSys.wSecond, ElTiSys.wMilliseconds);

_tprintf(_T("Пользовательское время: %02d:%02d:%02d:%03d\n"), UsTiSys.wHour, UsTiSys.wMinute, UsTiSys.wSecond, UsTiSys.wMilliseconds);

_tprintf(_T("Системное время: %02d:%02d:%02d:%03d\n"), KeTiSys.wHour, KeTiSys.wMinute, KeTiSys.wSecond, KeTiSys.wMilliseconds);

} else {

/* Windows 9x и СЕ. Вычисляется лишь истекшее время. */

}

CloseHandle(ProcInfo.hThread);

CloseHandle(ProcInfo.hProcess);

CloseHandle(hProc);

return 0;

}