日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux的top命令源码解析:RES指标

發布時間:2023/12/20 linux 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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的數值,

/** Build the information for a single task row and* display the results or return them to the caller. */ static const char *task_show (const WIN_t *q, const int idx) {... 省略....#define pages2K(n) (unsigned long)( (n) << Pg2K_shft )... 省略....// we must begin a row with a possible window number in mind...*(rp = rbuf) = '\0';if (Rc.mode_altscr) rp = scat(rp, " ");... 省略....for (x = 0; x < q->maxpflgs; x++) {const char *cp = NULL;FLG_t i = q->procflgs[x];... 省略....switch (i) {... 省略....case EU_MEM:cp = scale_pcnt((float)pages2K(p->resident) * 100 / kb_main_total, W, Jn);... 省略....case EU_NMA:cp = make_num(numa_node_of_cpu(p->processor), W, Jn, AUTOX_NO, 0);break;case EU_RES:cp = scale_mem(S, pages2K(p->resident), W, Jn);break;case EU_SHR:cp = scale_mem(S, pages2K(p->share), W, Jn);break;case EU_SWP:cp = scale_mem(S, p->vm_swap, W, Jn);break;... 省略....default: // keep gcc happycontinue;} // end: switch 'procflag'#undef pages2K } // end: task_show

其中RES獲取的片段如下:

其中p->resident 是res的數據源,p的結構:

proc_t *p = q->ppt[idx];

其中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函數傳遞進來:

static const char *task_show (const WIN_t *q, const int idx) {

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指标的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。