none
如何获取进程运行的时间长度 RRS feed

  • 常规讨论

  • 作者:DavidCrow

    编译:VCKBASE

    原文出处:How to retrieve the running-time of a process

    源代码下载

      本文简要介绍了如何使用 GetProcessTimes API 函数来获取某个进程运行了多长时间。GetProcessTimes 函数返回的时间值很容易转换成可读和可利用的信息。参考如下代码段:

    HANDLE hProcess;
    FILETIME ftCreation,
    ftExit,
    ftKernel,
    ftUser;
    
    GetProcessTimes(hProcess, &ftCreation, &ftExit, &ftKernel, &ftUser);

    本文例子程序的运行界面如下图所示:

    计算运行的时间

      某个进程运行的时间长度是指该进程创建的时间到当前时间逝去的时间。这个信息被存储在 FILETIME 结构中。只要计算出逝去的时间,那么再将它转换成小时/分钟/秒形式。很幸运,借助 COleDateTime 类,这个工作很容易完成。

    COleDateTime timeNow = COleDateTime::GetCurrentTime(),
    timeCreation = ftCreation;
    COleDateTimeSpan timeDiff = timeNow - timeCreation;

    在此你可以使用 COleDateTimeSpan 中不同的方法来获得逝去的小时/分钟等信息。

    计算内核和用户时间

      参考相关文档,内核和用户时间就是实际逝去的时间。这个值在 FILETIME 结构中被表示为 100 纳秒单位。将它转换成可用的信息有两种方法:

    方法一:

      我们可以用一些基本方法将它转换成以秒为单位的值,一纳秒相当于千万分之一秒,因为这个时间已经用 100 纳秒单位表示,所以用10个百万来除一下即可:

    __int64 i64Kernel = *((__int64 *) &ftKernel);
    DWORD dwKernel = (DWORD) (i64Kernel / 10000000U);
    除此之外,还可以使用联合数据类型:
    union
    {
    FILETIME ftKernel;
    __int64 i64Kernel;
    } timeKernel;
    
    timeKernel.ftKernel = ftKernel;
    DWORD dwKernel = (DWORD) (timeKernel.i64Kernel / 10000000U);

    不管哪种方法,dwKernel 都表示内核模式的进程运行逝去的秒数。再把秒数转换成小时/分钟/秒的形式就不难了。

    方法二:

    第二种方法只需要调用一个 API 函数就能搞掂,这个 API 函数就是 FileTimeToSystemTime,该函数将结果存储到 SYSTEMTIME 结构中,然后从结构中获取 wHour、wMinute 和 wSecond 成员。

    SYSTEMTIME stKernel;
    FileTimeToSystemTime(&ftKernel, &stKernel);
    用户模式时间的获取可以如法炮制。

    总结

    本文涉及的一些 API 函数调用如下:

    GetProcessTimes(hProcess, &ftCreation, &ftExit, &ftKernel, &ftUser);
    
    timeCreation = ftCreation;
    
    strData.Format("Created at %02d:%02d:%02d", timeCreation.GetHour(), 
    timeCreation.GetMinute(), timeCreation.GetSecond());
    
    timeDiff = timeNow - timeCreation;
    strData.Format("Elapsed time = %ud %uh %um %us", timeDiff.GetDays(), 
    timeDiff.GetHours(), timeDiff.GetMinutes(), 
    timeDiff.GetSeconds());
    
    FileTimeToSystemTime(&ftKernel, &stKernel);
    strData.Format("Time in kernel mode = %uh %um %us", stKernel.wHour,
    stKernel.wMinute, stKernel.wSecond);

    需要说明的一点是本文所述方法不能获取某些系统级进程的运行时间信息以及名称。需要另想办法实现。

    2009年6月1日 2:39