計(jì)算機(jī)二級:如何獲取進(jìn)程運(yùn)行的時(shí)間長度

字號:

本文簡要介紹了如何使用 GetProcessTimes API 函數(shù)來獲取某個(gè)進(jìn)程運(yùn)行了多長時(shí)間。GetProcessTimes 函數(shù)返回的時(shí)間值很容易轉(zhuǎn)換成可讀和可利用的信息。參考如下代碼段:
    HANDLE hProcess;
    FILETIME ftCreation,
    ftExit,
    ftKernel,
    ftUser;
    GetProcessTimes(hProcess, &ftCreation, &ftExit, &ftKernel, &ftUser);
    計(jì)算運(yùn)行的時(shí)間
    某個(gè)進(jìn)程運(yùn)行的時(shí)間長度是指該進(jìn)程創(chuàng)建的時(shí)間到當(dāng)前時(shí)間逝去的時(shí)間。這個(gè)信息被存儲(chǔ)在 FILETIME 結(jié)構(gòu)中。只要計(jì)算出逝去的時(shí)間,那么再將它轉(zhuǎn)換成小時(shí)/分鐘/秒形式。很幸運(yùn),借助 COleDateTime 類,這個(gè)工作很容易完成。
    COleDateTime timeNow = COleDateTime::GetCurrentTime(),
    timeCreation = ftCreation;
    COleDateTimeSpan timeDiff = timeNow - timeCreation;
    在此你可以使用 COleDateTimeSpan 中不同的方法來獲得逝去的小時(shí)/分鐘等信息。
    計(jì)算內(nèi)核和用戶時(shí)間
    參考相關(guān)文檔,內(nèi)核和用戶時(shí)間就是實(shí)際逝去的時(shí)間。這個(gè)值在 FILETIME 結(jié)構(gòu)中被表示為 100 納秒單位。將它轉(zhuǎn)換成可用的信息有兩種方法:
    方法一:
    我們可以用一些基本方法將它轉(zhuǎn)換成以秒為單位的值,一納秒相當(dāng)于千萬分之一秒,因?yàn)檫@個(gè)時(shí)間已經(jīng)用 100 納秒單位表示,所以用10個(gè)百萬來除一下即可:
    __int64 i64Kernel = *((__int64 *) &ftKernel);
    DWORD dwKernel = (DWORD) (i64Kernel / 10000000U);
    除此之外,還可以使用聯(lián)合數(shù)據(jù)類型:
    union
    {
    FILETIME ftKernel;
    __int64 i64Kernel;
    } timeKernel;
    timeKernel.ftKernel = ftKernel;
    DWORD dwKernel = (DWORD) (timeKernel.i64Kernel / 10000000U);
    不管哪種方法,dwKernel 都表示內(nèi)核模式的進(jìn)程運(yùn)行逝去的秒數(shù)。再把秒數(shù)轉(zhuǎn)換成小時(shí)/分鐘/秒的形式就不難了。
    方法二:
    第二種方法只需要調(diào)用一個(gè) API 函數(shù)就能搞掂,這個(gè) API 函數(shù)就是 FileTimeToSystemTime,該函數(shù)將結(jié)果存儲(chǔ)到 SYSTEMTIME 結(jié)構(gòu)中,然后從結(jié)構(gòu)中獲取 wHour、wMinute 和 wSecond 成員。
    SYSTEMTIME stKernel;
    FileTimeToSystemTime(&ftKernel, &stKernel);
    用戶模式時(shí)間的獲取可以如法炮制。
    總結(jié)
    本文涉及的一些 API 函數(shù)調(diào)用如下:
    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);
    需要說明的一點(diǎn)是本文所述方法不能獲取某些系統(tǒng)級進(jìn)程的運(yùn)行時(shí)間信息以及名稱。需要另想辦法實(shí)現(xiàn)。