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指标相关推荐
- Redis(六):list/lpush/lrange/lpop 命令源码解析
上一篇讲了hash数据类型的相关实现方法,没有茅塞顿开也至少知道redis如何搞事情的了吧. 本篇咱们继续来看redis中的数据类型的实现: list 相关操作实现. 同样,我们以使用者的角度,开始理 ...
- linux系统top命令:virt,res,shr详解
2019独角兽企业重金招聘Python工程师标准>>> VIRT:virtual memory usage 虚拟内存 1.进程"需要的"虚拟内存大小,包括进程使用 ...
- Redis(八):zset/zadd/zrange/zrembyscore 命令源码解析
前面几篇文章,我们完全领略了redis的string,hash,list,set数据类型的实现方法,相信对redis已经不再神秘. 本篇我们将介绍redis的最后一种数据类型: zset 的相关实现. ...
- ubuntu下top命令源码位置及分析
示例:查找top命令的源代码 第一步:使用 which命令查找 top所在的目录 $ which top /bin/ps/top 第二步:使用 sudo dpkg -S /bin/ps/top 查找该 ...
- android adb 命令源码解析
adb am start 这种命令是怎么就有结果了呢? 我怎么知道am都有哪些命令呢? 所有的这种命令都是继承自ShellCommand am 其实是ActivityManagerShellComma ...
- linux内核radeon gpu源码解析3 —— Radeon初始化
解析DRM代码,以从底层介绍显卡驱动的初始化过程,显卡类型是AMD的radeon r600以后的系列显卡.基本的过程就是驱动载入,硬件初始化,设置硬件独立的模块(如内存管理器),设置显示(分辨率等). ...
- Linux下的命令源码下载
1.首先安装dpkg-dev: apt-get install dpkg-dev 2.设置资源的URL 进入 sudo vim /etc/apt/sources.list ,然后加入以下URL: d ...
- linux中su命令源码,Linux中的su命令的详细解释
linxu下的su命令的主要作用是变更为其他使用者的身份执行命令,面由学习啦小编为大家整理了linux的su命令的详细解释的相关知识,希望对大家有帮助! 一.Linux中的su命令的详细解释 建议大家 ...
- linux中su命令源码,Linux-命令-su
1. 首先用help理解su, sudo su, sudo 2. 其次理解"login shell" and "interactive shell". &quo ...
最新文章
- 微服务架构与Docker容器之间关系
- Python for else 的使用(银行账号的登录)
- arping 帮助——翻译
- MySQL(八)子查询和分组查询
- AtCoder Regular Contest 058
- 记录一次bug解决过程:数据迁移
- 在STM32CubeMX生成的MDK5工程上添加RT-Thread Nano后双击工程名无法打开.map文件的解决方法
- Ajax:异步js和xml
- 2021年中国以太网测试设备市场趋势报告、技术动态创新及2027年市场预测
- 抹机王怎么一键新机_[电脑] [第六届机王争霸赛]水冷组——十年 by ilas 完工
- 第八届河南省赛D.引水工程(kruthcra+prime)
- Mac上双系统中Windows无法使用苹果鼠标键盘,如何处理
- 分析对象竞是我自己?我在 9 月上班划水 1510 分钟!
- 2021-10-10日 我的第一篇博客
- 【discuzx2】【家园广播】follow_feed.htm
- 乐得瑞LDR6282B 支持双C口盲插便携显示器驱动板方案
- js在赛码网中的输入/输出问题
- 从融360到理财魔方、再到韭菜财经,新金融正确姿势为哪般?
- [数学建模(四)]MATLAB神经网络工具箱的简单应用
- 搭建个人静态blog