linux的top命令源码解析:RES指标
CLion:2019.3.6
源碼管理平臺:Macbook Pro 10.12.6
C語言源碼程序:Makefile格式的linux系統的top命令源碼。
top所在的系統:ubuntu 14.04
一、源碼導入
linux的top命令采用的是procps-ng項目,可以通過Clion 導入Makefile格式的C語言源程序:procps項目 這篇博客將源碼進行下載和導入。
二、RES 指標的源碼分析
1、輸入top命令后顯示如下:
對于RES指標, 代表PID進程占用的物理內存,其中包括共享庫內存,RES的數據是怎么計算得來的呢,接下來我們將通過查看源碼來了解這個數據的源頭。
2、top的源碼分析
top的源碼位于top.c文件中:
top.c通過task_show如下進行獲取res的數值,
其中RES獲取的片段如下:
其中p->resident 是res的數據源,p的結構:
其中proc_t的結構體主要內容如下所示:
// Basic data structure which holds all information we can get about a process. // (unless otherwise specified, fields are read from /proc/#/stat) // // Most of it comes from task_struct in linux/sched.h // typedef struct proc_t { // 1st 16 bytesinttid, // (special) task id, the POSIX thread ID (see also: tgid)ppid; // stat,status pid of parent processunsigned long // next 2 fields are NOT filled in by readproc..........省略.........longpriority, // stat kernel scheduling prioritynice, // stat standard unix nice level of processrss, // stat identical to 'resident'alarm, // stat ?// the next 7 members come from /proc/#/statmsize, // statm total virtual memory (as # pages)resident, // statm resident non-swapped memory (as # pages)share, // statm shared (mmap'd) memory (as # pages)trs, // statm text (exe) resident set (as # pages)lrs, // statm library resident set (always 0 w/ 2.6)drs, // statm data+stack resident set (as # pages)dt; // statm dirty pages (always 0 w/ 2.6)unsigned longvm_size, // status equals 'size' (as kb)vm_lock, // status locked pages (as kb)vm_rss, // status equals 'rss' and/or 'resident' (as kb)vm_rss_anon, // status the 'anonymous' portion of vm_rss (as kb)vm_rss_file, // status the 'file-backed' portion of vm_rss (as kb)vm_rss_shared, // status the 'shared' portion of vm_rss (as kb)vm_data, // status data only size (as kb)vm_stack, // status stack only size (as kb)vm_swap, // status based on linux-2.6.34 "swap ents" (as kb)..........省略.........const char*lxcname; // n/a lxc container name } proc_t;所以top的res是從proc_t->resident獲取的,其中resident的單位是頁面,是通過pages2K將頁面數量轉換成字節數, 頁面的大小是4K:
case EU_RES:cp = scale_mem(S, pages2K(p->resident), W, Jn);其中pages2K函數:
/* The run-time acquired page stuff */static unsigned Pg2K_shft = 0;// get virtual page stuffi = page_bytes; // from sysinfo.c, at lib initwhile(i > 1024) { i >>= 1; Pg2K_shft++; }#define pages2K(n) (unsigned long)( (n) << Pg2K_shft )如上所示:q->ppt[idx]又是從哪兒初始化的呢?
如下代碼所示:q作為task_show函數傳遞進來:
WIN_t的結構定義如下:
/* This structure stores configurable information for each window.By expending a little effort in its creation and user requestedmaintenance, the only real additional per frame cost of havingwindows is an extra sort -- but that's just on pointers! */ typedef struct WIN_t {FLG_t pflgsall [PFLAGSSIZ], // all 'active/on' fieldscur, as enumprocflgs [PFLAGSSIZ]; // fieldscur subset, as enumRCW_t rc; // stuff that gets saved in the rcfileint winnum, // a window's number (array pos + 1)winlines, // current task window's rows (volatile)maxpflgs, // number of displayed procflgs ("on" in fieldscur)totpflgs, // total of displayable procflgs in pflgsall arraybegpflg, // scrolled beginning pos into pflgsall arrayendpflg, // scrolled ending pos into pflgsall arraybegtask, // scrolled beginning pos into Frame_maxtaskbegnext, // new scrolled delta for next frame's begtask #ifndef SCROLLVAR_NOvarcolbeg, // scrolled position within variable width col #endifvarcolsz, // max length of variable width column(s)usrseluid, // validated uid for 'u/U' user selectionusrseltyp, // the basis for matching above uidusrselflg, // flag denoting include/exclude matcheshdrcaplen; // column header xtra caps len, if anychar capclr_sum [CLRBUFSIZ], // terminfo strings built fromcapclr_msg [CLRBUFSIZ], // RCW_t colors (& rebuilt too),capclr_pmt [CLRBUFSIZ], // but NO recurring costs !capclr_hdr [CLRBUFSIZ], // note: sum, msg and pmt strscapclr_rowhigh [CLRBUFSIZ], // are only used when thiscapclr_rownorm [CLRBUFSIZ], // window is the 'Curwin'!cap_bold [CAPBUFSIZ], // support for View_NOBOLD togglegrpname [GRPNAMSIZ], // window number:name, printable #ifdef USE_X_COLHDRcolumnhdr [ROWMINSIZ], // column headings for procflgs #elsecolumnhdr [SCREENMAX], // column headings for procflgs #endif*captab [CAPTABMAX]; // captab needed by show_special()struct osel_s *osel_1st; // other selection criteria anchorint osel_tot; // total of other selection criteriachar *findstr; // window's current/active search stringint findlen; // above's strlen, without call overheadproc_t **ppt; // this window's proc_t ptr arraystruct WIN_t *next, // next window in window stack*prev; // prior window in window stack } WIN_t;關鍵的代碼在readproc.c,如下代碼所示:
// // This reads process info from /proc in the traditional way, for one process. // The pid (tgid? tid?) is already in p, and a path to it in path, with some // room to spare. static proc_t* simple_readproc(PROCTAB *restrict const PT, proc_t *restrict const p) {......省略.......if (flags & PROC_FILLMEM) { // read /proc/#/statmif (likely(file2str(path, "statm", &ub) != -1))statm2proc(ub.buf, p);}......省略.......其中statm2proc的函數實現如下:
static void statm2proc(const char* s, proc_t *restrict P) {sscanf(s, "%ld %ld %ld %ld %ld %ld %ld",&P->size, &P->resident, &P->share,&P->trs, &P->lrs, &P->drs, &P->dt); }可以看出,top的RES是從/proc/pid/statm文件中格式化讀出來的。
總結
以上是生活随笔為你收集整理的linux的top命令源码解析:RES指标的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 书信格式
- 下一篇: 你用过猿如意吗?猿如意可以使用ChatG