Linux如何查詢當(dāng)前進(jìn)程或線程的資源使用情況
在工作中,我們排除app出現(xiàn)的一些性能/資源問題時(shí),通常要先知道當(dāng)前app的資源使用情況,方能進(jìn)一步思考改進(jìn)措施。
獲取這些信息的途徑有很多,我這里簡(jiǎn)單分享下兩種:
1)從proc文件系統(tǒng);
2)通過Linux 的API函數(shù)。
一、/proc/[PID]/下的各個(gè)文件
1、proc簡(jiǎn)介
/proc 目錄是一個(gè)特殊的虛擬文件系統(tǒng),它提供了對(duì)內(nèi)核運(yùn)行時(shí)信息的訪問,包括進(jìn)程、設(shè)備、網(wǎng)絡(luò)、文件系統(tǒng)等各個(gè)方面的信息。
它不是一個(gè)真正的文件系統(tǒng),而是基于內(nèi)核數(shù)據(jù)結(jié)構(gòu)的一個(gè)接口,通過這個(gè)接口可以獲取系統(tǒng)的運(yùn)行時(shí)狀態(tài)。
下面是 /proc 目錄的一些重要子目錄和關(guān)鍵內(nèi)容的說明:
- /proc/[PID]:此目錄以進(jìn)程的 ID(PID)命名,并包含與該進(jìn)程有關(guān)的文件和目錄,如之前所講的 /proc/pid/目錄。
- /proc/cpuinfo:該文件包含有關(guān) CPU(處理器)的信息,如廠商、型號(hào)、頻率、緩存等。
- /proc/meminfo:該文件包含有關(guān)系統(tǒng)內(nèi)存的信息,如總內(nèi)存、可用內(nèi)存、緩存、交換分區(qū)等。
- /proc/mounts:此文件列出了系統(tǒng)上已掛載的文件系統(tǒng),包括文件系統(tǒng)類型、掛載點(diǎn)、掛載選項(xià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)核的運(yùn)行時(shí)行為。
- /proc/version:該文件包含了當(dāng)前正在運(yùn)行的內(nèi)核版本信息。
- /proc/cmdline:此文件包含了系統(tǒng)引導(dǎo)時(shí)傳遞給內(nèi)核的命令行參數(shù)。
- /proc/uptime:該文件包含自系統(tǒng)開機(jī)以來的運(yùn)行時(shí)間和空閑時(shí)間。
- /proc/sys/kernel/hostname:此文件包含主機(jī)的名稱(hostname)。
除了上述目錄和文件,/proc 目錄下還有很多其他文件和目錄,涵蓋了系統(tǒng)和進(jìn)程的各個(gè)方面的信息。
需要注意的是,/proc 目錄下的文件是動(dòng)態(tài)生成的,信息在進(jìn)程運(yùn)行時(shí)改變。讀取這些文件時(shí),請(qǐng)確保有足夠的權(quán)限,并理解每個(gè)文件的含義和用途。此外,不要輕易對(duì) /proc 目錄下的文件進(jìn)行修改,因?yàn)檫@可能會(huì)導(dǎo)致系統(tǒng)不穩(wěn)定或損壞。
2、/proc/[PID]/詳解
- arch_status: 該文件包含了有關(guān)進(jìn)程所運(yùn)行的指令集架構(gòu)的信息。例如,它可以顯示進(jìn)程在x86或ARM架構(gòu)上運(yùn)行。
- attr: 此目錄包含與進(jìn)程關(guān)聯(lián)的文件、目錄和進(jìn)程的訪問控制列表(ACL)信息。這些文件和目錄的訪問權(quán)限可以在這里進(jìn)行管理和修改。
- autogroup: 這個(gè)文件顯示了進(jìn)程是否被自動(dòng)控制分組,以限制對(duì)CPU資源的訪問。如果進(jìn)程分配給自動(dòng)控制分組,則該文件中的值為"1";否則,為"0"。
- auxv: 此文件包含了進(jìn)程的輔助向量信息,這些信息在加載動(dòng)態(tài)鏈接器時(shí)向其傳遞參數(shù)。輔助向量為動(dòng)態(tài)鏈接器提供有關(guān)進(jìn)程環(huán)境和運(yùn)行狀態(tài)的信息。
- cgroup: 該文件顯示了進(jìn)程所屬的控制組(cgroup)的路徑??刂平M是一種組織和限制進(jìn)程資源使用的方式。
- cmdline: 該文件包含了啟動(dòng)進(jìn)程時(shí)使用的命令行參數(shù),以null字符分隔各個(gè)參數(shù)??梢酝ㄟ^讀取該文件來獲取進(jìn)程的命令行參數(shù)信息。
- comm: 進(jìn)程的命令名可以通過這個(gè)文件獲得。它可以是可執(zhí)行文件名或進(jìn)程自描述。
- coredump_filter:這個(gè)文件決定了進(jìn)程在發(fā)生崩潰時(shí)生成核心轉(zhuǎn)儲(chǔ)(core dump)的內(nèi)容。通過修改該文件的值,可以控制生成核心轉(zhuǎn)儲(chǔ)時(shí)包含的內(nèi)容,這對(duì)于調(diào)試崩潰問題非常有用。可以使用 echo 命令將特定的值寫入這個(gè)文件中,以修改核心轉(zhuǎn)儲(chǔ)的行為。
- cpu_resctrl_groups:這個(gè)文件是與 CPU 資源控制(Resource Control)相關(guān)的,用于管理進(jìn)程對(duì)CPU資源的使用。通過這個(gè)文件,可以查詢或配置進(jìn)程關(guān)聯(lián)的 CPU ResCtrl(CPU資源控制)組的信息。CPU資源控制是用于管理和限制進(jìn)程對(duì)CPU資源的訪問的一種技術(shù),可以實(shí)現(xiàn)資源隔離、分配和監(jiān)控。
- cwd: 這是一個(gè)符號(hào)鏈接,指向進(jìn)程的當(dāng)前工作目錄(current working directory)。
- environ: 該文件包含了進(jìn)程的環(huán)境變量,以null字符分隔各個(gè)環(huán)境變量。通過讀取該文件,可以獲取進(jìn)程的環(huán)境變量信息。
- cpuset: 這個(gè)文件包含了進(jìn)程所屬的 cpuset(CPU affinity)的信息,可以用于管理進(jìn)程所能使用的 CPU 核心。 通過這個(gè)文件,可以查詢或設(shè)置進(jìn)程所在的 cpuset。
- exe:這是一個(gè)符號(hào)鏈接,指向進(jìn)程正在執(zhí)行的可執(zhí)行文件。通過讀取這個(gè)符號(hào)鏈接,可以獲取進(jìn)程當(dāng)前正在執(zhí)行的可執(zhí)行文件的路徑。
- fdinfo: 這個(gè)目錄包含了關(guān)于進(jìn)程打開的文件描述符(file descriptor)的詳細(xì)信息,如文件的偏移量(offset)等。
- gid_map:這個(gè)文件用于表示進(jìn)程的實(shí)際組ID(GID)與其用戶命名空間中的GID之間的映射關(guān)系。
- io:這個(gè)文件包含了有關(guān)進(jìn)程的輸入/輸出統(tǒng)計(jì)信息,如讀取和寫入的字節(jié)數(shù)、I/O操作次數(shù)等。
- limits:這個(gè)文件包含了對(duì)進(jìn)程資源限制的報(bào)告,顯示了一些限制項(xiàng)目的值,比如內(nèi)存限制、文件大小限制等。
- loginuid:這個(gè)文件記錄了與進(jìn)程關(guān)聯(lián)的登錄用戶ID(login UID)。
- map_files:這個(gè)目錄包含了進(jìn)程打開的映射文件的相關(guān)信息,可以用于查詢進(jìn)程當(dāng)前使用的文件映射情況。
- fd: 此目錄包含了進(jìn)程打開的文件描述符(file descriptor)的符號(hào)鏈接。可以通過查看這些符號(hào)鏈接來獲取進(jìn)程打開的文件等信息。
- maps: 該文件包含有關(guān)進(jìn)程內(nèi)存映射的信息,包括進(jìn)程的內(nèi)存地址范圍、映射的文件等。
- mounts: 此文件顯示了進(jìn)程的掛載點(diǎn)信息,包括進(jìn)程當(dāng)前掛載的各個(gè)文件系統(tǒng)的詳細(xì)數(shù)據(jù)。
- mem:這個(gè)文件允許對(duì)進(jìn)程的內(nèi)存空間進(jìn)行直接訪問,可以用于調(diào)試、內(nèi)存分析等目的。
- mountinfo:這個(gè)文件提供了有關(guān)進(jìn)程所掛載的文件系統(tǒng)的詳細(xì)信息,包括掛載點(diǎn)、掛載選項(xiàng)等。
- mountstats: 此文件包含了有關(guān)掛載點(diǎn)的統(tǒng)計(jì)信息,如 I/O 統(tǒng)計(jì)等。
- net:目錄包含了一系列與網(wǎng)絡(luò)相關(guān)的文件和子目錄,可以用于查詢進(jìn)程的網(wǎng)絡(luò)連接、端口等信息。
- ns:這個(gè)目錄包含了進(jìn)程的各種命名空間相關(guān)的符號(hào)鏈接,可以用于查詢和操作進(jìn)程的命名空間。
- numa_maps:這個(gè)文件包含了有關(guān)進(jìn)程內(nèi)存使用和NUMA節(jié)點(diǎn)分布情況的信息,對(duì)于了解進(jìn)程的NUMA相關(guān)性非常有用。
- oom_adj:這個(gè)文件包含了與進(jìn)程的OOM(Out Of Memory)分級(jí)相關(guān)的信息,用于調(diào)整進(jìn)程在內(nèi)存不足情況下被系統(tǒng)殺死的優(yōu)先級(jí)。
- oom_score:這個(gè)文件包含了進(jìn)程的OOM分?jǐn)?shù),用于在系統(tǒng)內(nèi)存不足時(shí)選擇性地終止進(jìn)程。
- oom_score_adj:與 oom_adj 類似,這個(gè)文件也用于調(diào)整進(jìn)程在內(nèi)存不足情況下被系統(tǒng)殺死的優(yōu)先級(jí)。
- pagemap:這個(gè)文件提供了有關(guān)進(jìn)程虛擬內(nèi)存頁面到物理內(nèi)存幀的映射信息,對(duì)于內(nèi)存管理方面的深入了解非常有用。
- patch_state:這個(gè)文件包含了有關(guān)進(jìn)程的內(nèi)核安全補(bǔ)丁狀態(tài)的信息,通常用于安全審計(jì)和補(bǔ)丁管理。
- personality: 這個(gè)文件包含了與進(jìn)程的運(yùn)行環(huán)境和虛擬機(jī)架構(gòu)相關(guān)的信息,用于指定進(jìn)程的特定行為。
- projid_map:在用戶命名空間中使用的文件,用于表示進(jìn)程實(shí)際項(xiàng)目ID(Project ID)與其用戶命名空間中的項(xiàng)目ID之間的映射關(guān)系。
- root:這是一個(gè)符號(hào)鏈接,指向進(jìn)程的根目錄。
- sched:這個(gè)文件提供了與進(jìn)程調(diào)度策略和優(yōu)先級(jí)相關(guān)的信息,包括當(dāng)前調(diào)度策略、優(yōu)先級(jí)等。
- schedstat:這個(gè)文件包含了與進(jìn)程調(diào)度統(tǒng)計(jì)相關(guān)的信息,如運(yùn)行時(shí)間、等待時(shí)間等。
- sessionid:這個(gè)文件記錄了與進(jìn)程關(guān)聯(lián)的會(huì)話ID。
- setgroups:這個(gè)文件包含了與進(jìn)程的附加組(supplementary group)相關(guān)的信息。
- smaps:這個(gè)文件提供了詳細(xì)的進(jìn)程內(nèi)存映射信息,包括每個(gè)內(nèi)存區(qū)域的權(quán)限、大小、映射文件等。
- smaps_rollup: 類似于 smaps 文件,但提供了按文件和庫合并的內(nèi)存映射信息,用于更簡(jiǎn)潔的內(nèi)存分析。
- stack:這個(gè)文件記錄了進(jìn)程的當(dāng)前棧的內(nèi)容。
- stat: 這個(gè)文件提供了與進(jìn)程狀態(tài)相關(guān)的信息,如進(jìn)程ID、父進(jìn)程ID、運(yùn)行狀態(tài)等。
- statm:這個(gè)文件提供了與進(jìn)程內(nèi)存使用量相關(guān)的信息,包括進(jìn)程的總內(nèi)存、共享內(nèi)存、庫內(nèi)存、堆內(nèi)存等。
- status:這個(gè)文件提供了有關(guān)進(jìn)程的多種信息,包括進(jìn)程狀態(tài)、內(nèi)存使用、文件描述符等。
- syscall:這個(gè)目錄包含與進(jìn)程相關(guān)的系統(tǒng)調(diào)用信息,可以用于跟蹤和分析進(jìn)程的系統(tǒng)調(diào)用。
- task:這個(gè)目錄包含了進(jìn)程的所有線程(task)的信息。
- timens_offsets:這個(gè)文件提供了與進(jìn)程關(guān)聯(lián)的時(shí)間命名空間偏移量的信息,用于跟蹤進(jìn)程的時(shí)間命名空間變化。
- timers:這個(gè)目錄包含了與進(jìn)程相關(guān)的定時(shí)器的信息,如定時(shí)器ID、時(shí)間值等。
- timerslack_ns:這個(gè)文件包含了與進(jìn)程的定時(shí)器松弛值(timerslack)有關(guān)的信息,用于調(diào)整進(jìn)程的定時(shí)行為。
- uid_map:這個(gè)文件用于表示進(jìn)程的實(shí)際用戶ID(UID)與其用戶命名空間中的UID之間的映射關(guān)系。
- wchan:是一個(gè)用于描繪一個(gè)進(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)試以及資源管理方面,對(duì)于普通用戶來說可能并不經(jīng)常需要直接操作這些文件。通過讀取這些文件,可以了解并監(jiān)視系統(tǒng)中各個(gè)進(jìn)程的情況。請(qǐng)注意,有些文件是符號(hào)鏈接,需要使用readlink
或ls -l
等命令來獲取其指向的真實(shí)路徑。
知識(shí)補(bǔ)充:
命名空間(Namespace)在Linux系統(tǒng)中是一種用于隔離系統(tǒng)資源的機(jī)制。它允許在同一臺(tái)物理機(jī)上創(chuàng)建多個(gè)隔離的環(huán)境,每個(gè)環(huán)境可以擁有自己獨(dú)立的資源實(shí)例,例如進(jìn)程ID、掛載點(diǎn)、網(wǎng)絡(luò)、用戶等。這種隔離使得不同的進(jìn)程能夠在同一系統(tǒng)上運(yùn)行,而彼此之間互不干擾。
在Linux中,有多種類型的命名空間,包括但不限于以下幾種:
- PID 命名空間(PID Namespace):使得進(jìn)程擁有自己獨(dú)立的進(jìn)程ID空間,進(jìn)程在不同的PID命名空間中可以擁有相同的PID而不會(huì)相互影響。
- 掛載命名空間(Mount Namespace):使得進(jìn)程擁有獨(dú)立的文件系統(tǒng)掛載點(diǎn),不同的掛載命名空間中可以有不同的文件系統(tǒng)視圖。
- 網(wǎng)絡(luò)命名空間(Network Namespace):允許每個(gè)命名空間中擁有獨(dú)立的網(wǎng)絡(luò)設(shè)備、IP地址等網(wǎng)絡(luò)資源,實(shí)現(xiàn)網(wǎng)絡(luò)隔離。
- IPC 命名空間(IPC Namespace):用于隔離進(jìn)程間通信資源,如消息隊(duì)列和共享內(nèi)存等。
- UTS 命名空間(UTS Namespace):用于隔離系統(tǒng)標(biāo)識(shí),如主機(jī)名等。
- 用戶命名空間(User Namespace):允許分配不同的用戶和組ID給進(jìn)程,從而實(shí)現(xiàn)用戶隔離。
通過使用命名空間,容器技術(shù)得以實(shí)現(xiàn),并且不同的容器可以在相互隔離的環(huán)境中運(yùn)行,從而實(shí)現(xiàn)更高效的資源利用和更好的安全性。
二、通過Linux API獲取當(dāng)前進(jìn)程或線程的資源使用情況
要獲取當(dāng)前進(jìn)程或線程的資源使用情況,可以使用Linux提供的一些系統(tǒng)調(diào)用或API。
以下是一些常用的方法:
1、getrusage
getrusage
是一個(gè)用于獲取進(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
用于指定獲取資源使用情況的對(duì)象,包括以下兩個(gè)選項(xiàng):
- RUSAGE_SELF: 獲取當(dāng)前進(jìn)程的資源使用情況。
- RUSAGE_CHILDREN: 獲取當(dāng)前進(jìn)程創(chuàng)建的所有子進(jìn)程的資源使用情況的匯總信息。
參數(shù) usage
是一個(gè)指向 struct rusage 結(jié)構(gòu)體的指針,用于存儲(chǔ)獲取到的資源使用情況信息。
//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
:用戶級(jí)別的 CPU 時(shí)間(執(zhí)行用戶程序的時(shí)間)。ru_stime
:系統(tǒng)級(jí)別的 CPU 時(shí)間(執(zhí)行系統(tǒng)調(diào)用的時(shí)間)。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)生的次缺頁錯(cuò)誤(對(duì)不存在的內(nèi)存頁面發(fā)生的訪問,需要從硬盤加載)。ru_majflt
:產(chǎn)生的主缺頁錯(cuò)誤(必須從硬盤加載數(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ā)出的信號(hào)數(shù)。ru_nvcsw
:從等待狀態(tài)喚醒的上下文切換次數(shù)(通過虛擬終端 I/O、文件系統(tǒng)路徑名查找、等待 CPU 時(shí)間等方式)。ru_nivcsw
:無法滿足進(jìn)程需求而導(dǎo)致的上下文切換次數(shù)。
這些資源使用情況信息對(duì)于進(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
是一個(gè)用于等待子進(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
:用于指定等待的選項(xiàng),包括一些控制子進(jìn)程狀態(tài)獲取行為的選項(xiàng)。rusage
:用于獲取子進(jìn)程的資源使用情況信息,即上一條回答中提到的struct rusage
結(jié)構(gòu)體。
wait4
函數(shù)會(huì)阻塞父進(jìn)程,直到指定的子進(jìn)程結(jié)束。當(dāng)子進(jìn)程結(jié)束后,父進(jìn)程將獲得子進(jìn)程的退出狀態(tài)信息存儲(chǔ)在 status
中,并且如果傳入了 rusage
參數(shù),則會(huì)獲取子進(jìn)程的資源使用情況信息。
通常情況下,wait4
函數(shù)與 fork
函數(shù)結(jié)合使用,父進(jìn)程通過 fork
創(chuàng)建子進(jìn)程,然后通過 wait4
等待子進(jìn)程結(jié)束,并獲取其狀態(tài)信息。這樣可以實(shí)現(xiàn)父子進(jìn)程之間的同步和協(xié)作。
#include <sys/resource.h> int main() { struct rusage usage; getrusage(RUSAGE_SELF, &usage); // 打印CPU時(shí)間 printf("CPU時(shí)間: %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
是一個(gè)用于獲取系統(tǒng)信息的系統(tǒng)調(diào)用函數(shù),在 Linux 系統(tǒng)中的頭文件 <sys/sysinfo.h>
中定義。
函數(shù)原型如下:
int sysinfo(struct sysinfo *info);
參數(shù) info
是一個(gè)指向 struct sysinfo
結(jié)構(gòu)體的指針,用于存儲(chǔ)獲取到的系統(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)運(yùn)行的時(shí)間(以秒為單位)。unsigned long loads[3]
:系統(tǒng)的平均負(fù)載值,分別代表過去1分鐘、5分鐘和15分鐘的平均負(fù)載。這些值是無符號(hào)長(zhǎng)整型數(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
來獲取具體錯(cuò)誤信息。
#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é)果,這是因?yàn)?sysinfo
結(jié)構(gòu)體中的 loads
數(shù)組使用了 unsigned long
類型。
在 Linux 內(nèi)核中,負(fù)載值是以固定點(diǎn)數(shù)的格式表示的,使用了定點(diǎn)數(shù)表示方式來保留小數(shù)部分。在這里,每個(gè)負(fù)載值都被乘以了 2^16(65536),以便將小數(shù)部分轉(zhuǎn)換為整數(shù)。
這種表示方式的好處在于,它可以比較精確地表示系統(tǒng)的負(fù)載情況,同時(shí)又不需要使用浮點(diǎn)數(shù)來表示,因?yàn)楦↑c(diǎn)數(shù)的運(yùn)算會(huì)耗費(fèi)相對(duì)更多的 CPU 時(shí)間。通過將負(fù)載值乘以一個(gè)固定的倍數(shù)(2^16),可以在不犧牲太多精度的情況下,使用整數(shù)進(jìn)行表示和計(jì)算,這樣會(huì)更高效。
當(dāng)我們從 struct sysinfo
結(jié)構(gòu)體中獲取負(fù)載值時(shí),需要將其除以 2^16 來得到真實(shí)的負(fù)載值。例如,在上面的示例代碼中,打印負(fù)載值時(shí)并沒有除以 2^16,因此實(shí)際的負(fù)載值應(yīng)當(dāng)是 info.loads[x] / 65536
才能得到系統(tǒng)的實(shí)際負(fù)載情況。
總之,通過將負(fù)載值乘以 2^16 來表示,Linux 內(nèi)核可以在保持較高精度的同時(shí),使用更高效的整數(shù)表示方式,用于存儲(chǔ)和計(jì)算系統(tǒng)的負(fù)載情況。
3、times
times
函數(shù)是一個(gè)用于獲取進(jìn)程和子進(jìn)程的系統(tǒng)和用戶 CPU 時(shí)間的系統(tǒng)調(diào)用,其原型如下:
#include <sys/times.h> clock_t times(struct tms *buf);
buf
是一個(gè)指向tms
結(jié)構(gòu)的指針,它用來存儲(chǔ) CPU 時(shí)間的信息。
struct tms
結(jié)構(gòu)包含了進(jìn)程和子進(jìn)程的 CPU 時(shí)間信息,其定義如下:
struct tms { clock_t tms_utime; // 進(jìn)程在用戶態(tài)花費(fèi)的時(shí)間 clock_t tms_stime; // 進(jìn)程在內(nèi)核態(tài)花費(fèi)的時(shí)間 clock_t tms_cutime; // 所有已終止子進(jìn)程在用戶態(tài)花費(fèi)的時(shí)間 clock_t tms_cstime; // 所有已終止子進(jìn)程在內(nèi)核態(tài)花費(fèi)的時(shí)間 };
tms_utime
表示進(jìn)程在用戶態(tài)花費(fèi)的 CPU 時(shí)間。tms_stime
表示進(jìn)程在內(nèi)核態(tài)花費(fèi)的 CPU 時(shí)間。tms_cutime
表示所有已終止子進(jìn)程在用戶態(tài)花費(fèi)的 CPU 時(shí)間。tms_cstime
表示所有已終止子進(jìn)程在內(nèi)核態(tài)花費(fèi)的 CPU 時(shí)間。
示例代碼如下所示,演示了如何使用 times
函數(shù)來獲取進(jìn)程的 CPU 時(shí)間信息:
#include <stdio.h> #include <sys/times.h> #include <time.h> #include <unistd.h> int main() { struct tms tms_buf; clock_t start, end; // 獲取起始時(shí)間 start = times(&tms_buf); printf("Starting time: %ld\n", start); // 模擬一些工作 for (int i = 0; i < 100000000; ++i) { // do something } // 獲取結(jié)束時(shí)間 end = times(&tms_buf); printf("Ending time: %ld\n", end); // 計(jì)算 CPU 時(shí)間消耗 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; }
這個(gè)示例代碼中,我們首先調(diào)用 times
函數(shù)獲取了進(jìn)程的 CPU 時(shí)間信息,并輸出了起始時(shí)間。然后進(jìn)行了一些模擬工作,之后再次調(diào)用 times
函數(shù)獲取了結(jié)束時(shí)間,最后計(jì)算了用戶態(tài)和內(nèi)核態(tài)的 CPU 時(shí)間消耗。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Linux內(nèi)核設(shè)備驅(qū)動(dòng)地址映射筆記整理
今天小編就為大家分享一篇關(guān)于Linux內(nèi)核設(shè)備驅(qū)動(dòng)地址映射筆記整理,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12Centos 6和Centos 7下服務(wù)啟動(dòng)方法及添加到開機(jī)啟動(dòng)項(xiàng)的方法
這篇文章主要介紹了Centos 6和Centos 7下服務(wù)啟動(dòng)方法及添加到開機(jī)啟動(dòng)項(xiàng)的方法的相關(guān)資料,需要的朋友可以參考下2016-10-10Linux如何定時(shí)清空日志內(nèi)容和刪除日志文件
這篇文章主要介紹了Linux如何定時(shí)清空日志內(nèi)容和刪除日志文件,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12linux查找大文件指定內(nèi)容的實(shí)現(xiàn)方法
今天小編就為大家分享一篇linux查找大文件指定內(nèi)容的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-07-07關(guān)于linux分區(qū),文件系統(tǒng),目錄結(jié)構(gòu)的概述
下面小編就為大家?guī)硪黄P(guān)于linux分區(qū),文件系統(tǒng),目錄結(jié)構(gòu)的概述。小編覺得挺不錯(cuò)的?,F(xiàn)在就分享給大家。也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-12-12nacos在linux下啟動(dòng)startup.sh報(bào)錯(cuò)問題及解決
遇到Nacos啟動(dòng)錯(cuò)誤提示“Permission denied”,可通過執(zhí)行命令chmod u+x *.sh給予startup.sh執(zhí)行權(quán)限,解決權(quán)限問題,啟動(dòng)成功,這是一種常見的解決Linux下腳本執(zhí)行權(quán)限問題的方法2023-03-03如何在ubuntu18.04中設(shè)置使用中文輸入法的使用
這篇文章主要介紹了如何在ubuntu18.04中設(shè)置使用中文輸入法的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12