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指标相关推荐

  1. Redis(六):list/lpush/lrange/lpop 命令源码解析

    上一篇讲了hash数据类型的相关实现方法,没有茅塞顿开也至少知道redis如何搞事情的了吧. 本篇咱们继续来看redis中的数据类型的实现: list 相关操作实现. 同样,我们以使用者的角度,开始理 ...

  2. linux系统top命令:virt,res,shr详解

    2019独角兽企业重金招聘Python工程师标准>>> VIRT:virtual memory usage 虚拟内存 1.进程"需要的"虚拟内存大小,包括进程使用 ...

  3. Redis(八):zset/zadd/zrange/zrembyscore 命令源码解析

    前面几篇文章,我们完全领略了redis的string,hash,list,set数据类型的实现方法,相信对redis已经不再神秘. 本篇我们将介绍redis的最后一种数据类型: zset 的相关实现. ...

  4. ubuntu下top命令源码位置及分析

    示例:查找top命令的源代码 第一步:使用 which命令查找 top所在的目录 $ which top /bin/ps/top 第二步:使用 sudo dpkg -S /bin/ps/top 查找该 ...

  5. android adb 命令源码解析

    adb am start 这种命令是怎么就有结果了呢? 我怎么知道am都有哪些命令呢? 所有的这种命令都是继承自ShellCommand am 其实是ActivityManagerShellComma ...

  6. linux内核radeon gpu源码解析3 —— Radeon初始化

    解析DRM代码,以从底层介绍显卡驱动的初始化过程,显卡类型是AMD的radeon r600以后的系列显卡.基本的过程就是驱动载入,硬件初始化,设置硬件独立的模块(如内存管理器),设置显示(分辨率等). ...

  7. Linux下的命令源码下载

    1.首先安装dpkg-dev: apt-get install dpkg-dev 2.设置资源的URL 进入 sudo vim /etc/apt/sources.list  ,然后加入以下URL: d ...

  8. linux中su命令源码,Linux中的su命令的详细解释

    linxu下的su命令的主要作用是变更为其他使用者的身份执行命令,面由学习啦小编为大家整理了linux的su命令的详细解释的相关知识,希望对大家有帮助! 一.Linux中的su命令的详细解释 建议大家 ...

  9. linux中su命令源码,Linux-命令-su

    1. 首先用help理解su, sudo su, sudo 2. 其次理解"login shell" and "interactive shell". &quo ...

最新文章

  1. 微服务架构与Docker容器之间关系
  2. Python for else 的使用(银行账号的登录)
  3. arping 帮助——翻译
  4. MySQL(八)子查询和分组查询
  5. AtCoder Regular Contest 058
  6. 记录一次bug解决过程:数据迁移
  7. 在STM32CubeMX生成的MDK5工程上添加RT-Thread Nano后双击工程名无法打开.map文件的解决方法
  8. Ajax:异步js和xml
  9. 2021年中国以太网测试设备市场趋势报告、技术动态创新及2027年市场预测
  10. 抹机王怎么一键新机_[电脑] [第六届机王争霸赛]水冷组——十年 by ilas 完工
  11. 第八届河南省赛D.引水工程(kruthcra+prime)
  12. Mac上双系统中Windows无法使用苹果鼠标键盘,如何处理
  13. 分析对象竞是我自己?我在 9 月上班划水 1510 分钟!
  14. 2021-10-10日 我的第一篇博客
  15. 【discuzx2】【家园广播】follow_feed.htm
  16. 乐得瑞LDR6282B 支持双C口盲插便携显示器驱动板方案
  17. js在赛码网中的输入/输出问题
  18. 从融360到理财魔方、再到韭菜财经,新金融正确姿势为哪般?
  19. [数学建模(四)]MATLAB神经网络工具箱的简单应用
  20. 搭建个人静态blog

热门文章

  1. Centos服务器重启后无法打开网站的解决方案
  2. 身材火辣的“飞盘媛”,可能藏着灰色产业链
  3. t20天正结构v7.0破姐 安装教程
  4. 用神经网络表示与逻辑,对神经网络的简单理解
  5. 智慧高速 3D 可视化,构建互联协同智能交通体系
  6. deltav 安装说明
  7. mt4 部分内置函数
  8. uniapp实现微信扫二维码进行核销
  9. 易推流为什么显示连接服务器失败,live-pusher 推流总是失败?
  10. 嵌入式开发第二阶段,系统编程