Linux C進程時間:牆上時鍾時間,用戶CPU時間,系統CPU時鍾時間


1. 進程運行時間的概念

如何度量進程的運行時間?
可以用times函數獲取進程的牆上時鍾時間,用戶CPU時間,系統CPU時鍾時間。

1.1 牆上時鍾時間

牆上時鍾時間 wall clock time: 又簡稱時鍾時間,從進程開始運行到結束,系統時鍾走過的時間(時鍾數),包含了進程阻塞、等待的時間。
每秒鍾嘀嗒數, 可通過sysconf(_SC_CLK_TCK)獲取

注意: 如果調用clock()計算進程/算法運行時間, 是不包括阻塞(含sleep)時間的.

1.2 用戶CPU時間

用戶CPU時間:用戶進程在用戶態執行時間。

1.3 系統CPU時間

系統CPU時間:用戶進程在內核態執行時間。

1.4 三者之間關系

(牆上)時鍾時間 = 阻塞時間 + 就緒時間 + 運行時間
運行時間 = 用戶CPU時間 + 系統CPU時間


2. 如何獲取進程相關運行時間?

2.1 times函數

獲取進程時間

原型

#include <sys/times.h>

clock_t times(struct tms *buf);

tms結構:

struct tms {
    clock_t tms_utime;  /* user CPU time */
    clock_t tms_stime;  /* system CPU time */
    clock_t tms_cutime; /* user CPU time,terminated children */
    clock_t tms_cstime; /* system CPU time,terminated children */
};

功能
獲取當前進程牆上時鍾時間,用戶CPU時間,系統CPU時鍾時間

返回值
1.函數返回牆上時鍾時間。
進程開始和結束時,可以分別獲取到2個返回值,做差值即為進程的牆上時鍾時間。運行時間足夠長可能溢出(可能性較小)

2.輸出參數buf,包含用戶CPU時間,系統CPU時間。

2.2 getrusage 函數

獲取資源使用(統計情況).
getrusage 也可以用於獲取進程的用戶CPU時間, 系統CPU時間, 而且適用於多進程、多線程環境, 功能比times函數更強大.

#include <sys/time.h>
#include <sys/resource.h>

int getrusage(int who, struct rusage *usage);
  • 參數
    who 函數getrusage能返回何種資源使用測量值, 取決於who參數:
    1)RUSAGE_SELF 返回調用進程所有線程的資源使用統計;

2)RUSAGE_CHILDREN 返回調用進程的所有已終止子進程的資源使用統計;

3)RUSAGE_THREAD 返回調用線程的資源使用統計, 不過要求_GNU_SOURCE已在<sys/resource.h>.中定義;

usage 指向rusage結構, 包含了用戶CPU時間, 系統CPU時間,

struct rusage {
   struct timeval ru_utime; /* user CPU time used 使用了的用戶CPU時間 */
   struct timeval ru_stime; /* system CPU time used 使用了的系統CPU時間 */
   long   ru_maxrss;        /* maximum resident set size 最大占用物理內存大小(瞬時值, 單位KB)  */
   long   ru_ixrss;         /* integral shared memory size 完整的共享內存大小, linux未使用 */
   long   ru_idrss;         /* integral unshared data size 完整的非共享數據大小, linux未使用 */
   long   ru_isrss;         /* integral unshared stack size 完整的非共享棧大小, linux未使用 */
   long   ru_minflt;        /* page reclaims (soft page faults)  soft page faults次數: 需要訪問的內存不在虛擬地址空間,但是在物理內存, 需要MMU建立和物理內存的映射. 不需要IO活動 */
   long   ru_majflt;        /* page faults (hard page faults) hard page faults次數: 需要訪問的內存不在虛擬地址空間,也不在物理內存中,需要從慢速設備載入. 需要IO活動 */
   long   ru_nswap;         /* swaps linux未使用 */
   long   ru_inblock;       /* block input operations 阻塞輸入操作次數 */
   long   ru_oublock;       /* block output operations 阻塞輸出操作次數 */
   long   ru_msgsnd;        /* IPC messages sent linux未使用 */
   long   ru_msgrcv;        /* IPC messages received linux未使用 */
   long   ru_nsignals;      /* signals received linux未使用 */
   long   ru_nvcsw;         /* voluntary context switches 主動上下文切換(時間片用完)時間數 */
   long   ru_nivcsw;        /* involuntary context switches 被動上下午切換(更高優先級進程搶占)時間數 */
};

2.3 getrusage例子

利用getrusage打印總的用戶CPU時間, 總的系統CPU時間.

void
pr_cpu_time(void)
{
    double user, sys;
    struct rusage myusage, childusage;
    
    /* 調用進程資源利用統計 */
    if (getrusage(RUSAGE_SELF, &myusage) < 0) 
        err_sys("getrusage error");
    /* 調用進程已終止子進程資源利用統計 */
    if (getrusage(RUSAGE_CHILDREN, &myusage) < 0) 
        err_sys("getrusage error");

    user = (double) myusage.ru_utime.tv_sec + myusage.ru_utime.tv_usec / 1000000.0;
    user = (double) childusage.ru_utime.tv_sec + childusage.ru_utime.tv_usec / 1000000.0;

    sys = (double) myusage.ru_stime.tv_sec + myusage.ru_stime.tv_usec / 1000000.0;
    sys = (double) childusage.ru_stime.tv_sec + childusage.ru_stime.tv_usec / 1000000.0;
    
    /* 打印用戶CPU時間, 系統CPU時間. %g 根據結果自動選擇輸出格式%f, %e, 科學計數法 */
    printf("user time = %g, sys time = %g\n", user, sys);
}

參考

牆上時鍾時間 ,用戶cpu時間 ,系統cpu時間 | 知乎


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM