Linux如何查詢當(dāng)前進(jìn)程或線程的資源使用情況
在工作中,我們排除app出現(xiàn)的一些性能/資源問題時,通常要先知道當(dāng)前app的資源使用情況,方能進(jìn)一步思考改進(jìn)措施。
獲取這些信息的途徑有很多,我這里簡單分享下兩種:
1)從proc文件系統(tǒng);
2)通過Linux 的API函數(shù)。
一、/proc/[PID]/下的各個文件
1、proc簡介
/proc 目錄是一個特殊的虛擬文件系統(tǒng),它提供了對內(nèi)核運行時信息的訪問,包括進(jìn)程、設(shè)備、網(wǎng)絡(luò)、文件系統(tǒng)等各個方面的信息。
它不是一個真正的文件系統(tǒng),而是基于內(nèi)核數(shù)據(jù)結(jié)構(gòu)的一個接口,通過這個接口可以獲取系統(tǒng)的運行時狀態(tài)。
下面是 /proc 目錄的一些重要子目錄和關(guān)鍵內(nèi)容的說明:
- /proc/[PID]:此目錄以進(jìn)程的 ID(PID)命名,并包含與該進(jìn)程有關(guān)的文件和目錄,如之前所講的 /proc/pid/目錄。
- /proc/cpuinfo:該文件包含有關(guān) CPU(處理器)的信息,如廠商、型號、頻率、緩存等。
- /proc/meminfo:該文件包含有關(guān)系統(tǒng)內(nèi)存的信息,如總內(nèi)存、可用內(nèi)存、緩存、交換分區(qū)等。
- /proc/mounts:此文件列出了系統(tǒng)上已掛載的文件系統(tǒng),包括文件系統(tǒng)類型、掛載點、掛載選項等信息。
- /proc/net:此目錄包含有關(guān)網(wǎng)絡(luò)協(xié)議、接口和連接的信息,如 /proc/net/tcp、/proc/net/udp 等文件。
- /proc/sys:此目錄包含與內(nèi)核參數(shù)和系統(tǒng)配置相關(guān)的文件??梢酝ㄟ^讀寫這些文件來修改內(nèi)核的運行時行為。
- /proc/version:該文件包含了當(dāng)前正在運行的內(nèi)核版本信息。
- /proc/cmdline:此文件包含了系統(tǒng)引導(dǎo)時傳遞給內(nèi)核的命令行參數(shù)。
- /proc/uptime:該文件包含自系統(tǒng)開機(jī)以來的運行時間和空閑時間。
- /proc/sys/kernel/hostname:此文件包含主機(jī)的名稱(hostname)。
除了上述目錄和文件,/proc 目錄下還有很多其他文件和目錄,涵蓋了系統(tǒng)和進(jìn)程的各個方面的信息。
需要注意的是,/proc 目錄下的文件是動態(tài)生成的,信息在進(jìn)程運行時改變。讀取這些文件時,請確保有足夠的權(quán)限,并理解每個文件的含義和用途。此外,不要輕易對 /proc 目錄下的文件進(jìn)行修改,因為這可能會導(dǎo)致系統(tǒng)不穩(wěn)定或損壞。
2、/proc/[PID]/詳解

- arch_status: 該文件包含了有關(guān)進(jìn)程所運行的指令集架構(gòu)的信息。例如,它可以顯示進(jìn)程在x86或ARM架構(gòu)上運行。
- attr: 此目錄包含與進(jìn)程關(guān)聯(lián)的文件、目錄和進(jìn)程的訪問控制列表(ACL)信息。這些文件和目錄的訪問權(quán)限可以在這里進(jìn)行管理和修改。
- autogroup: 這個文件顯示了進(jìn)程是否被自動控制分組,以限制對CPU資源的訪問。如果進(jìn)程分配給自動控制分組,則該文件中的值為"1";否則,為"0"。
- auxv: 此文件包含了進(jìn)程的輔助向量信息,這些信息在加載動態(tài)鏈接器時向其傳遞參數(shù)。輔助向量為動態(tài)鏈接器提供有關(guān)進(jìn)程環(huán)境和運行狀態(tài)的信息。
- cgroup: 該文件顯示了進(jìn)程所屬的控制組(cgroup)的路徑??刂平M是一種組織和限制進(jìn)程資源使用的方式。
- cmdline: 該文件包含了啟動進(jìn)程時使用的命令行參數(shù),以null字符分隔各個參數(shù)??梢酝ㄟ^讀取該文件來獲取進(jìn)程的命令行參數(shù)信息。
- comm: 進(jìn)程的命令名可以通過這個文件獲得。它可以是可執(zhí)行文件名或進(jìn)程自描述。
- coredump_filter:這個文件決定了進(jìn)程在發(fā)生崩潰時生成核心轉(zhuǎn)儲(core dump)的內(nèi)容。通過修改該文件的值,可以控制生成核心轉(zhuǎn)儲時包含的內(nèi)容,這對于調(diào)試崩潰問題非常有用??梢允褂?echo 命令將特定的值寫入這個文件中,以修改核心轉(zhuǎn)儲的行為。
- cpu_resctrl_groups:這個文件是與 CPU 資源控制(Resource Control)相關(guān)的,用于管理進(jìn)程對CPU資源的使用。通過這個文件,可以查詢或配置進(jìn)程關(guān)聯(lián)的 CPU ResCtrl(CPU資源控制)組的信息。CPU資源控制是用于管理和限制進(jìn)程對CPU資源的訪問的一種技術(shù),可以實現(xiàn)資源隔離、分配和監(jiān)控。
- cwd: 這是一個符號鏈接,指向進(jìn)程的當(dāng)前工作目錄(current working directory)。
- environ: 該文件包含了進(jìn)程的環(huán)境變量,以null字符分隔各個環(huán)境變量。通過讀取該文件,可以獲取進(jìn)程的環(huán)境變量信息。
- cpuset: 這個文件包含了進(jìn)程所屬的 cpuset(CPU affinity)的信息,可以用于管理進(jìn)程所能使用的 CPU 核心。 通過這個文件,可以查詢或設(shè)置進(jìn)程所在的 cpuset。
- exe:這是一個符號鏈接,指向進(jìn)程正在執(zhí)行的可執(zhí)行文件。通過讀取這個符號鏈接,可以獲取進(jìn)程當(dāng)前正在執(zhí)行的可執(zhí)行文件的路徑。
- fdinfo: 這個目錄包含了關(guān)于進(jìn)程打開的文件描述符(file descriptor)的詳細(xì)信息,如文件的偏移量(offset)等。
- gid_map:這個文件用于表示進(jìn)程的實際組ID(GID)與其用戶命名空間中的GID之間的映射關(guān)系。
- io:這個文件包含了有關(guān)進(jìn)程的輸入/輸出統(tǒng)計信息,如讀取和寫入的字節(jié)數(shù)、I/O操作次數(shù)等。
- limits:這個文件包含了對進(jìn)程資源限制的報告,顯示了一些限制項目的值,比如內(nèi)存限制、文件大小限制等。
- loginuid:這個文件記錄了與進(jìn)程關(guān)聯(lián)的登錄用戶ID(login UID)。
- map_files:這個目錄包含了進(jìn)程打開的映射文件的相關(guān)信息,可以用于查詢進(jìn)程當(dāng)前使用的文件映射情況。
- fd: 此目錄包含了進(jìn)程打開的文件描述符(file descriptor)的符號鏈接??梢酝ㄟ^查看這些符號鏈接來獲取進(jìn)程打開的文件等信息。
- maps: 該文件包含有關(guān)進(jìn)程內(nèi)存映射的信息,包括進(jìn)程的內(nèi)存地址范圍、映射的文件等。
- mounts: 此文件顯示了進(jìn)程的掛載點信息,包括進(jìn)程當(dāng)前掛載的各個文件系統(tǒng)的詳細(xì)數(shù)據(jù)。
- mem:這個文件允許對進(jìn)程的內(nèi)存空間進(jìn)行直接訪問,可以用于調(diào)試、內(nèi)存分析等目的。
- mountinfo:這個文件提供了有關(guān)進(jìn)程所掛載的文件系統(tǒng)的詳細(xì)信息,包括掛載點、掛載選項等。
- mountstats: 此文件包含了有關(guān)掛載點的統(tǒng)計信息,如 I/O 統(tǒng)計等。
- net:目錄包含了一系列與網(wǎng)絡(luò)相關(guān)的文件和子目錄,可以用于查詢進(jìn)程的網(wǎng)絡(luò)連接、端口等信息。
- ns:這個目錄包含了進(jìn)程的各種命名空間相關(guān)的符號鏈接,可以用于查詢和操作進(jìn)程的命名空間。
- numa_maps:這個文件包含了有關(guān)進(jìn)程內(nèi)存使用和NUMA節(jié)點分布情況的信息,對于了解進(jìn)程的NUMA相關(guān)性非常有用。
- oom_adj:這個文件包含了與進(jìn)程的OOM(Out Of Memory)分級相關(guān)的信息,用于調(diào)整進(jìn)程在內(nèi)存不足情況下被系統(tǒng)殺死的優(yōu)先級。
- oom_score:這個文件包含了進(jìn)程的OOM分?jǐn)?shù),用于在系統(tǒng)內(nèi)存不足時選擇性地終止進(jìn)程。
- oom_score_adj:與 oom_adj 類似,這個文件也用于調(diào)整進(jìn)程在內(nèi)存不足情況下被系統(tǒng)殺死的優(yōu)先級。
- pagemap:這個文件提供了有關(guān)進(jìn)程虛擬內(nèi)存頁面到物理內(nèi)存幀的映射信息,對于內(nèi)存管理方面的深入了解非常有用。
- patch_state:這個文件包含了有關(guān)進(jìn)程的內(nèi)核安全補(bǔ)丁狀態(tài)的信息,通常用于安全審計和補(bǔ)丁管理。
- personality: 這個文件包含了與進(jìn)程的運行環(huán)境和虛擬機(jī)架構(gòu)相關(guān)的信息,用于指定進(jìn)程的特定行為。
- projid_map:在用戶命名空間中使用的文件,用于表示進(jìn)程實際項目ID(Project ID)與其用戶命名空間中的項目ID之間的映射關(guān)系。
- root:這是一個符號鏈接,指向進(jìn)程的根目錄。
- sched:這個文件提供了與進(jìn)程調(diào)度策略和優(yōu)先級相關(guān)的信息,包括當(dāng)前調(diào)度策略、優(yōu)先級等。
- schedstat:這個文件包含了與進(jìn)程調(diào)度統(tǒng)計相關(guān)的信息,如運行時間、等待時間等。
- sessionid:這個文件記錄了與進(jìn)程關(guān)聯(lián)的會話ID。
- setgroups:這個文件包含了與進(jìn)程的附加組(supplementary group)相關(guān)的信息。
- smaps:這個文件提供了詳細(xì)的進(jìn)程內(nèi)存映射信息,包括每個內(nèi)存區(qū)域的權(quán)限、大小、映射文件等。
- smaps_rollup: 類似于 smaps 文件,但提供了按文件和庫合并的內(nèi)存映射信息,用于更簡潔的內(nèi)存分析。
- stack:這個文件記錄了進(jìn)程的當(dāng)前棧的內(nèi)容。
- stat: 這個文件提供了與進(jìn)程狀態(tài)相關(guān)的信息,如進(jìn)程ID、父進(jìn)程ID、運行狀態(tài)等。
- statm:這個文件提供了與進(jìn)程內(nèi)存使用量相關(guān)的信息,包括進(jìn)程的總內(nèi)存、共享內(nèi)存、庫內(nèi)存、堆內(nèi)存等。
- status:這個文件提供了有關(guān)進(jìn)程的多種信息,包括進(jìn)程狀態(tài)、內(nèi)存使用、文件描述符等。
- syscall:這個目錄包含與進(jìn)程相關(guān)的系統(tǒng)調(diào)用信息,可以用于跟蹤和分析進(jìn)程的系統(tǒng)調(diào)用。
- task:這個目錄包含了進(jìn)程的所有線程(task)的信息。
- timens_offsets:這個文件提供了與進(jìn)程關(guān)聯(lián)的時間命名空間偏移量的信息,用于跟蹤進(jìn)程的時間命名空間變化。
- timers:這個目錄包含了與進(jìn)程相關(guān)的定時器的信息,如定時器ID、時間值等。
- timerslack_ns:這個文件包含了與進(jìn)程的定時器松弛值(timerslack)有關(guān)的信息,用于調(diào)整進(jìn)程的定時行為。
- uid_map:這個文件用于表示進(jìn)程的實際用戶ID(UID)與其用戶命名空間中的UID之間的映射關(guān)系。
- wchan:是一個用于描繪一個進(jìn)程在等待什么的內(nèi)核函數(shù)指針。它表示了進(jìn)程當(dāng)前正在等待的內(nèi)核函數(shù)或系統(tǒng)調(diào)用??捎糜谡{(diào)試和分析進(jìn)程的等待狀態(tài)。
這些文件和目錄提供了關(guān)于特定進(jìn)程的多種信息,如進(jìn)程狀態(tài)、資源使用情況、環(huán)境變量等,通常被用于性能調(diào)優(yōu)、調(diào)試以及資源管理方面,對于普通用戶來說可能并不經(jīng)常需要直接操作這些文件。通過讀取這些文件,可以了解并監(jiān)視系統(tǒng)中各個進(jìn)程的情況。請注意,有些文件是符號鏈接,需要使用readlink或ls -l等命令來獲取其指向的真實路徑。
知識補(bǔ)充:
命名空間(Namespace)在Linux系統(tǒng)中是一種用于隔離系統(tǒng)資源的機(jī)制。它允許在同一臺物理機(jī)上創(chuàng)建多個隔離的環(huán)境,每個環(huán)境可以擁有自己獨立的資源實例,例如進(jìn)程ID、掛載點、網(wǎng)絡(luò)、用戶等。這種隔離使得不同的進(jìn)程能夠在同一系統(tǒng)上運行,而彼此之間互不干擾。
在Linux中,有多種類型的命名空間,包括但不限于以下幾種:
- PID 命名空間(PID Namespace):使得進(jìn)程擁有自己獨立的進(jìn)程ID空間,進(jìn)程在不同的PID命名空間中可以擁有相同的PID而不會相互影響。
- 掛載命名空間(Mount Namespace):使得進(jìn)程擁有獨立的文件系統(tǒng)掛載點,不同的掛載命名空間中可以有不同的文件系統(tǒng)視圖。
- 網(wǎng)絡(luò)命名空間(Network Namespace):允許每個命名空間中擁有獨立的網(wǎng)絡(luò)設(shè)備、IP地址等網(wǎng)絡(luò)資源,實現(xiàn)網(wǎng)絡(luò)隔離。
- IPC 命名空間(IPC Namespace):用于隔離進(jìn)程間通信資源,如消息隊列和共享內(nèi)存等。
- UTS 命名空間(UTS Namespace):用于隔離系統(tǒng)標(biāo)識,如主機(jī)名等。
- 用戶命名空間(User Namespace):允許分配不同的用戶和組ID給進(jìn)程,從而實現(xiàn)用戶隔離。
通過使用命名空間,容器技術(shù)得以實現(xiàn),并且不同的容器可以在相互隔離的環(huán)境中運行,從而實現(xiàn)更高效的資源利用和更好的安全性。
二、通過Linux API獲取當(dāng)前進(jìn)程或線程的資源使用情況
要獲取當(dāng)前進(jìn)程或線程的資源使用情況,可以使用Linux提供的一些系統(tǒng)調(diào)用或API。
以下是一些常用的方法:
1、getrusage
getrusage 是一個用于獲取進(jìn)程或線程的資源使用情況的系統(tǒng)調(diào)用函數(shù),在 Linux 系統(tǒng)中的頭文件 <sys/resource.h> 中定義。
#include <sys/time.h> #include <sys/resource.h> int getrusage(int who, struct rusage *usage);
參數(shù)who用于指定獲取資源使用情況的對象,包括以下兩個選項:
- RUSAGE_SELF: 獲取當(dāng)前進(jìn)程的資源使用情況。
- RUSAGE_CHILDREN: 獲取當(dāng)前進(jìn)程創(chuàng)建的所有子進(jìn)程的資源使用情況的匯總信息。
參數(shù) usage 是一個指向 struct rusage 結(jié)構(gòu)體的指針,用于存儲獲取到的資源使用情況信息。
//struct rusage 結(jié)構(gòu)體包含了一系列字段,用于表示不同類型的資源使用情況
struct rusage {
struct timeval ru_utime; /* user CPU time used */
struct timeval ru_stime; /* system CPU time used */
long ru_maxrss; /* maximum resident set size */
long ru_ixrss; /* integral shared memory size */
long ru_idrss; /* integral unshared data size */
long ru_isrss; /* integral unshared stack size */
long ru_minflt; /* page reclaims (soft page faults) */
long ru_majflt; /* page faults (hard page faults) */
long ru_nswap; /* swaps */
long ru_inblock; /* block input operations */
long ru_oublock; /* block output operations */
long ru_msgsnd; /* IPC messages sent */
long ru_msgrcv; /* IPC messages received */
long ru_nsignals; /* signals received */
long ru_nvcsw; /* voluntary context switches */
long ru_nivcsw; /* involuntary context switches */
};
ru_utime:用戶級別的 CPU 時間(執(zhí)行用戶程序的時間)。ru_stime:系統(tǒng)級別的 CPU 時間(執(zhí)行系統(tǒng)調(diào)用的時間)。ru_maxrss:進(jìn)程最大的常駐內(nèi)存大?。ㄒ?KB 為單位)。ru_ixrss:進(jìn)程的共享內(nèi)存大小。ru_idrss:進(jìn)程的非共享數(shù)據(jù)段的大小。ru_isrss:進(jìn)程的棧大小。ru_minflt:產(chǎn)生的次缺頁錯誤(對不存在的內(nèi)存頁面發(fā)生的訪問,需要從硬盤加載)。ru_majflt:產(chǎn)生的主缺頁錯誤(必須從硬盤加載數(shù)據(jù))。ru_nswap:發(fā)生的交換次數(shù)(從內(nèi)存到磁盤或反之)。ru_inblock:從塊設(shè)備讀取的次數(shù)。ru_oublock:向塊設(shè)備寫入的次數(shù)。ru_msgsnd:發(fā)送的消息數(shù)。ru_msgrcv:接收的消息數(shù)。ru_nsignals:發(fā)出的信號數(shù)。ru_nvcsw:從等待狀態(tài)喚醒的上下文切換次數(shù)(通過虛擬終端 I/O、文件系統(tǒng)路徑名查找、等待 CPU 時間等方式)。ru_nivcsw:無法滿足進(jìn)程需求而導(dǎo)致的上下文切換次數(shù)。
這些資源使用情況信息對于進(jìn)程性能分析和系統(tǒng)監(jiān)控非常有用。getrusage 函數(shù)返回的資源使用情況是關(guān)于當(dāng)前進(jìn)程或線程的信息。要獲取其他進(jìn)程的資源使用情況,需要使用相應(yīng)的進(jìn)程相關(guān)的系統(tǒng)調(diào)用(如 wait4),并將返回的 rusage 結(jié)構(gòu)體作為參數(shù)傳遞給 wait4。
wait4 是一個用于等待子進(jìn)程結(jié)束并獲取其狀態(tài)信息的系統(tǒng)調(diào)用函數(shù)。在 Linux 系統(tǒng)中的頭文件 <sys/wait.h> 中定義。wait4 函數(shù)的原型為:
pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage);
其中參數(shù)含義如下:
pid:指定要等待的子進(jìn)程的 ID。傳入-1表示等待任意子進(jìn)程結(jié)束。status:用于獲取子進(jìn)程的退出狀態(tài)信息。options:用于指定等待的選項,包括一些控制子進(jìn)程狀態(tài)獲取行為的選項。rusage:用于獲取子進(jìn)程的資源使用情況信息,即上一條回答中提到的struct rusage結(jié)構(gòu)體。
wait4 函數(shù)會阻塞父進(jìn)程,直到指定的子進(jìn)程結(jié)束。當(dāng)子進(jìn)程結(jié)束后,父進(jìn)程將獲得子進(jìn)程的退出狀態(tài)信息存儲在 status 中,并且如果傳入了 rusage 參數(shù),則會獲取子進(jìn)程的資源使用情況信息。
通常情況下,wait4 函數(shù)與 fork 函數(shù)結(jié)合使用,父進(jìn)程通過 fork 創(chuàng)建子進(jìn)程,然后通過 wait4 等待子進(jìn)程結(jié)束,并獲取其狀態(tài)信息。這樣可以實現(xiàn)父子進(jìn)程之間的同步和協(xié)作。
#include <sys/resource.h>
int main() {
struct rusage usage;
getrusage(RUSAGE_SELF, &usage);
// 打印CPU時間
printf("CPU時間: %ld.%06ld 秒\n", usage.ru_utime.tv_sec, usage.ru_utime.tv_usec);
// 打印最大使用的內(nèi)存
printf("最大內(nèi)存使用量: %ld 字節(jié)\n", usage.ru_maxrss);
// 其他資源使用情況,可以在usage結(jié)構(gòu)體中查看
// ...
return 0;
}
2、sysinfo
sysinfo 是一個用于獲取系統(tǒng)信息的系統(tǒng)調(diào)用函數(shù),在 Linux 系統(tǒng)中的頭文件 <sys/sysinfo.h> 中定義。
函數(shù)原型如下:
int sysinfo(struct sysinfo *info);
參數(shù) info 是一個指向 struct sysinfo 結(jié)構(gòu)體的指針,用于存儲獲取到的系統(tǒng)信息。
//Since Linux 2.3.23 (i386) and Linux 2.3.48 (all architectures) the structure is:
struct sysinfo {
long uptime; /* Seconds since boot */
unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
unsigned long totalram; /* Total usable main memory size */
unsigned long freeram; /* Available memory size */
unsigned long sharedram; /* Amount of shared memory */
unsigned long bufferram; /* Memory used by buffers */
unsigned long totalswap; /* Total swap space size */
unsigned long freeswap; /* Swap space still available */
unsigned short procs; /* Number of current processes */
unsigned long totalhigh; /* Total high memory size */
unsigned long freehigh; /* Available high memory size */
unsigned int mem_unit; /* Memory unit size in bytes */
char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding to 64 bytes */
};
long uptime:系統(tǒng)已經(jīng)運行的時間(以秒為單位)。unsigned long loads[3]:系統(tǒng)的平均負(fù)載值,分別代表過去1分鐘、5分鐘和15分鐘的平均負(fù)載。這些值是無符號長整型數(shù),表示了負(fù)載值乘以 2^16 的結(jié)果。unsigned long totalram:系統(tǒng)總共的物理內(nèi)存大?。ㄒ宰止?jié)為單位)。unsigned long freeram:系統(tǒng)可用的物理內(nèi)存大?。ㄒ宰止?jié)為單位)。unsigned long sharedram:被共享的物理內(nèi)存大小(以字節(jié)為單位)。unsigned long bufferram:被用作緩沖區(qū)的物理內(nèi)存大小(以字節(jié)為單位)。unsigned long totalswap:交換空間的總大?。ㄒ宰止?jié)為單位)。unsigned long freeswap:可用的交換空間大?。ㄒ宰止?jié)為單位)。unsigned short procs:當(dāng)前進(jìn)程數(shù)量。unsigned long totalhigh:可用的高位內(nèi)存大?。ㄒ宰止?jié)為單位)。unsigned long freehigh:空閑的高位內(nèi)存大?。ㄒ宰止?jié)為單位)。unsigned int mem_unit:內(nèi)存單元大?。ㄒ宰止?jié)為單位)。
sysinfo 函數(shù)的返回值為 0 表示成功,-1 表示失敗,并且可以通過 errno 來獲取具體錯誤信息。
#include <sys/sysinfo.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
struct sysinfo info;
sysinfo(&info);
// 打印總內(nèi)存大小
printf("總內(nèi)存大小: %ld 字節(jié)\n", info.totalram * info.mem_unit);
// 打印已使用內(nèi)存大小
printf("已使用內(nèi)存大小: %ld 字節(jié)\n", (info.totalram - info.freeram) * info.mem_unit);
// 其他資源使用情況,可以在info結(jié)構(gòu)體中查看
// ...
return 0;
}
在struct sysinfo 結(jié)構(gòu)體中,loads 數(shù)組中的數(shù)值表示了負(fù)載值乘以 2^16 的結(jié)果,這是因為 sysinfo 結(jié)構(gòu)體中的 loads 數(shù)組使用了 unsigned long 類型。
在 Linux 內(nèi)核中,負(fù)載值是以固定點數(shù)的格式表示的,使用了定點數(shù)表示方式來保留小數(shù)部分。在這里,每個負(fù)載值都被乘以了 2^16(65536),以便將小數(shù)部分轉(zhuǎn)換為整數(shù)。
這種表示方式的好處在于,它可以比較精確地表示系統(tǒng)的負(fù)載情況,同時又不需要使用浮點數(shù)來表示,因為浮點數(shù)的運算會耗費相對更多的 CPU 時間。通過將負(fù)載值乘以一個固定的倍數(shù)(2^16),可以在不犧牲太多精度的情況下,使用整數(shù)進(jìn)行表示和計算,這樣會更高效。
當(dāng)我們從 struct sysinfo 結(jié)構(gòu)體中獲取負(fù)載值時,需要將其除以 2^16 來得到真實的負(fù)載值。例如,在上面的示例代碼中,打印負(fù)載值時并沒有除以 2^16,因此實際的負(fù)載值應(yīng)當(dāng)是 info.loads[x] / 65536 才能得到系統(tǒng)的實際負(fù)載情況。
總之,通過將負(fù)載值乘以 2^16 來表示,Linux 內(nèi)核可以在保持較高精度的同時,使用更高效的整數(shù)表示方式,用于存儲和計算系統(tǒng)的負(fù)載情況。
3、times
times 函數(shù)是一個用于獲取進(jìn)程和子進(jìn)程的系統(tǒng)和用戶 CPU 時間的系統(tǒng)調(diào)用,其原型如下:
#include <sys/times.h> clock_t times(struct tms *buf);
buf是一個指向tms結(jié)構(gòu)的指針,它用來存儲 CPU 時間的信息。
struct tms 結(jié)構(gòu)包含了進(jìn)程和子進(jìn)程的 CPU 時間信息,其定義如下:
struct tms {
clock_t tms_utime; // 進(jìn)程在用戶態(tài)花費的時間
clock_t tms_stime; // 進(jìn)程在內(nèi)核態(tài)花費的時間
clock_t tms_cutime; // 所有已終止子進(jìn)程在用戶態(tài)花費的時間
clock_t tms_cstime; // 所有已終止子進(jìn)程在內(nèi)核態(tài)花費的時間
};
tms_utime表示進(jìn)程在用戶態(tài)花費的 CPU 時間。tms_stime表示進(jìn)程在內(nèi)核態(tài)花費的 CPU 時間。tms_cutime表示所有已終止子進(jìn)程在用戶態(tài)花費的 CPU 時間。tms_cstime表示所有已終止子進(jìn)程在內(nèi)核態(tài)花費的 CPU 時間。
示例代碼如下所示,演示了如何使用 times 函數(shù)來獲取進(jìn)程的 CPU 時間信息:
#include <stdio.h>
#include <sys/times.h>
#include <time.h>
#include <unistd.h>
int main() {
struct tms tms_buf;
clock_t start, end;
// 獲取起始時間
start = times(&tms_buf);
printf("Starting time: %ld\n", start);
// 模擬一些工作
for (int i = 0; i < 100000000; ++i) {
// do something
}
// 獲取結(jié)束時間
end = times(&tms_buf);
printf("Ending time: %ld\n", end);
// 計算 CPU 時間消耗
clock_t user_time = tms_buf.tms_utime;
clock_t sys_time = tms_buf.tms_stime;
printf("User CPU time: %ld\n", user_time);
printf("System CPU time: %ld\n", sys_time);
return 0;
}
這個示例代碼中,我們首先調(diào)用 times 函數(shù)獲取了進(jìn)程的 CPU 時間信息,并輸出了起始時間。然后進(jìn)行了一些模擬工作,之后再次調(diào)用 times 函數(shù)獲取了結(jié)束時間,最后計算了用戶態(tài)和內(nèi)核態(tài)的 CPU 時間消耗。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Linux內(nèi)核設(shè)備驅(qū)動地址映射筆記整理
今天小編就為大家分享一篇關(guān)于Linux內(nèi)核設(shè)備驅(qū)動地址映射筆記整理,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-12-12
Centos 6和Centos 7下服務(wù)啟動方法及添加到開機(jī)啟動項的方法
這篇文章主要介紹了Centos 6和Centos 7下服務(wù)啟動方法及添加到開機(jī)啟動項的方法的相關(guān)資料,需要的朋友可以參考下2016-10-10
linux查找大文件指定內(nèi)容的實現(xiàn)方法
今天小編就為大家分享一篇linux查找大文件指定內(nèi)容的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-07-07
關(guān)于linux分區(qū),文件系統(tǒng),目錄結(jié)構(gòu)的概述
下面小編就為大家?guī)硪黄P(guān)于linux分區(qū),文件系統(tǒng),目錄結(jié)構(gòu)的概述。小編覺得挺不錯的?,F(xiàn)在就分享給大家。也給大家做個參考。一起跟隨小編過來看看吧2016-12-12
nacos在linux下啟動startup.sh報錯問題及解決
遇到Nacos啟動錯誤提示“Permission denied”,可通過執(zhí)行命令chmod u+x *.sh給予startup.sh執(zhí)行權(quán)限,解決權(quán)限問題,啟動成功,這是一種常見的解決Linux下腳本執(zhí)行權(quán)限問題的方法2023-03-03
如何在ubuntu18.04中設(shè)置使用中文輸入法的使用
這篇文章主要介紹了如何在ubuntu18.04中設(shè)置使用中文輸入法的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12

