- Windows Processes and Threads
- Process Creation
- Process Handle Counts
- Process Identities
- Duplicating Handles
- Exiting and Terminating a Process
- Waiting for a Process to Terminate
- Environment Blocks and Strings
- Example: Parallel Pattern Searching
- Processes in a Multiprocessor Environment
- Process Execution Times
- Example: Process Execution Times
- Generating Console Control Events
- Example: Simple Job Management
- Job Objects
- Summary
- Exercises
Example: Process Execution Times
The next example (Program 6-2) is a command called timep (time print) that is similar to the UNIX time command (time is supported by the command prompt, so a different name is required). Elapsed, kernel, and system times can be printed, although only elapsed time is available on Windows 9x.
One use for this command is to compare the execution times and efficiencies of the various file copy and ASCII to Unicode functions implemented in previous chapters.
This program uses GetCommandLine, a Windows function that returns the complete command line as a single string rather than individual argv strings.
The program also uses a utility function, SkipArg, to scan the command line and skip past the executable name. The SkipArg listing is in Appendix A.
Program 6-2 uses the GetVersionEx function to determine the OS version. With Windows 9x and CE, only the elapsed time is available. The code for these systems is shown to illustrate that a program can, in some cases, be made to operate, at least partially, on a range of Windows versions.
Example 6-2. timep: Process Times
/* Chapter 6. timep. */ #include "EvryThng.h" int _tmain (int argc, LPTSTR argv []) { STARTUPINFO StartUp; PROCESS_INFORMATION ProcInfo; union { /* Structure required for file time arithmetic. */ 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 (all versions) returns VER_PLATFORM_WIN32_NT. */ GetStartupInfo (&StartUp); GetSystemTime (&StartTimeSys); /* Execute the command line; wait for process to complete. */ CreateProcess (NULL, targv, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &StartUp, &ProcInfo); /* Assure that we have all REQUIRED access to the process. */ DuplicateHandle (GetCurrentProcess (), ProcInfo.hProcess, GetCurrentProcess (), &hProc, PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, 0); WaitForSingleObject (hProc, INFINITE); GetSystemTime (&ExitTimeSys); if (IsNT) { /* W NT. Elapsed, Kernel, & User times. */ 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 ("Real Time: %02d:%02d:%02d:%03d\n"), ElTiSys.wHour, ElTiSys.wMinute, ElTiSys.wSecond, ElTiSys.wMilliseconds); _tprintf (_T ("User Time: %02d:%02d:%02d:%03d\n"), UsTiSys.wHour, UsTiSys.wMinute, UsTiSys.wSecond, UsTiSys.wMilliseconds); _tprintf (_T ("Sys Time: %02d:%02d:%02d:%03d\n"), KeTiSys.wHour, KeTiSys.wMinute, KeTiSys.wSecond, KeTiSys.wMilliseconds); } else { /* Windows 9x and CE. Elapsed time only. */ ... } CloseHandle (ProcInfo.hThread); CloseHandle (ProcInfo.hProcess); CloseHandle (hProc); return 0; }
Using the timep Command
timep can now be used to compare the various ASCII to Unicode file copy and sorting utilities such as atou (Program 2-4) and sortMM (Program 5-5). Appendix C summarizes and briefly analyzes some results.
Notice that measuring a program such as grepMP (Program 6-1) gives kernel and user times only for the parent process. Job objects, described near the end of this chapter, allow you to collect information on a group of processes. Appendix C shows that, on an SMP system, performance can improve as the separate processes, or more accurately, threads, run on different processors. There can also be performance gains if the files are on different physical drives.