Linux系统的文件类型大致可分为三类: 普通文件, 目录文件和伪文件. 伪文件不是用来存储数据的, 因此这些文件不占用磁盘空间, 只是存在于内存中. /proc 让你可以与内核内部数据进行交互, 获取有关进程的有用信息.(为了更好阅读,参考https://blog.csdn.net/whatday/article/details/104147981

下面主要介绍一下 /proc 下面的四个文件: /proc/stat , /proc/meminfo /proc/<pid>/stat /proc/<pid>/status .

/proc/stat 存放系统的cpu时间, 该文件包含了所有cpu活动的信息.

  1.  
    cpu 72389 2891 16811 1148664 31374 0 67 0 0 0
  2.  
    cpu0 17608 452 3786 288899 6210 0 30 0 0 0
  3.  
    cpu1 18724 926 4598 285844 8911 0 15 0 0 0
  4.  
    cpu2 16803 658 3726 288710 7220 0 7 0 0 0
  5.  
    cpu3 19254 855 4700 285209 9032 0 13 0 0 0
  6.  
    ...
  7.  
    ...
  8.  
    ...

/proc/meminfo 存放系统的内存信息, 通过文件中各个变量的名字便可知其代表的信息.

  1.  
    MemTotal: 4046236 kB
  2.  
    MemFree:  1054440 kB
  3.  
    MemAvailable: 2460060 kB
  4.  
    Buffers:  359688 kB
  5.  
    Cached:  1158056 kB
  6.  
    SwapCached:  0 kB
  7.  
    Active:  2020096 kB
  8.  
    Inactive:  677948 kB
  9.  
    Active(anon): 1181376 kB
  10.  
     
  11.  
    ...
  12.  
    ...
  13.  
    ...

/proc/<pid>/stat 存放某个进程的cpu信息

  1.  
     
  2.  
    2476 (firefox) S 1773 1910 1910 0 -1 4210688 3413511 1712 757 1 45466 4629 2 7 20 0 57 0 20381 1774743552 150565 18446744073709551615 94844693012480 94844693126372 140732961864784 140732961858304 139747170914269 0 0 4096 33572079 0 0 0 17 2 0 0 1178 0 0 94844695226592 94844695228536 94844713955328 140732961867643 140732961867668 140732961867668 140732961869791 0

/proc/<pid>/status 存放某个进程的cpu信息以及一些综合信息

  1.  
    Name: firefox
  2.  
    State: S (sleeping)
  3.  
    Tgid: 2476
  4.  
    Ngid: 0
  5.  
    Pid: 2476
  6.  
    PPid: 1773
  7.  
    TracerPid: 0
  8.  
    Uid: 1000 1000 1000 1000
  9.  
    Gid: 1000 1000 1000 1000
  10.  
    FDSize: 256
  11.  
    Groups: 4 24 27 30 46 108 124 1000
  12.  
    NStgid: 2476
  13.  
    NSpid: 2476
  14.  
    NSpgid: 1910
  15.  
    NSsid: 1910
  16.  
    VmPeak: 1722812 kB
  17.  
    VmSize: 1690920 kB
  18.  
    VmLck:   0 kB
  19.  
    VmPin:   0 kB
  20.  
    VmHWM: 684048 kB
  21.  
    VmRSS: 600324 kB
  22.  
    VmData: 993040 kB
  23.  
    VmStk:  192 kB
  24.  
    ...
  25.  
    ...
  26.  
    ...

以上数据都可以通过文件读取的方式来获取. 根据自己实验的需要可以计算相应的数据, 比如 pmem = VmRSS/MemTotal*100 等等.

示例代码

下面只是贴出一个简单的获取某进程当前时刻所占用的实际内存的c代码实现例子.

  1.  
    // get_mem.h
  2.  
    #include <stdlib.h>
  3.  
    #include <stdio.h>
  4.  
    #include <stdlib.h>
  5.  
    #include <unistd.h>
  6.  
    #include <assert.h>
  7.  
    #define VMRSS_LINE 21// VMRSS所在行, 注:根据不同的系统,位置可能有所区别.
  8.  
    #define pid_t int
  9.  
     
  10.  
     
  11.  
    int get_memory_by_pid(pid_t p)
  12.  
    {
  13.  
    FILE *fd;
  14.  
    char name[32], line_buff[256] = {0}, file[64] = {0};
  15.  
    int i, vmrss = 0;
  16.  
     
  17.  
     
  18.  
    sprintf(file, "/proc/%d/status", p);
  19.  
    // 以R读的方式打开文件再赋给指针fd
  20.  
    fd = fopen(file, "r");
  21.  
    if(fd==NULL)
  22.  
    {
  23.  
    return -1;
  24.  
    }
  25.  
     
  26.  
    // 读取VmRSS这一行的数据
  27.  
    for (i = 0; i < 40; i++)
  28.  
    {
  29.  
    if (fgets(line_buff, sizeof(line_buff), fd) == NULL)
  30.  
    {
  31.  
    break;
  32.  
    }
  33.  
    if (strstr(line_buff, "VmRSS:1") != NULL)
  34.  
    {
  35.  
    sscanf(line_buff, "%s %d", name, &vmrss);
  36.  
    break;
  37.  
    }
  38.  
    }
  39.  
     
  40.  
    fclose(fd);
  41.  
     
  42.  
    return vmrss;
  43.  
    }
  44.  
     
  45.  
    int get_total_mem()
  46.  
    {
  47.  
    const char *file = "/proc/meminfo";// 文件名
  48.  
    FILE *fd;
  49.  
     
  50.  
    // 定义文件指针fd
  51.  
    char line_buff[256] = {0}; // 读取行的缓冲区
  52.  
     
  53.  
     
  54.  
    fd = fopen (file, "r"); // 以R读的方式打开文件再赋给指针fd
  55.  
    // 获取memtotal:总内存占用大小
  56.  
    int i;
  57.  
    char name[32];// 存放项目名称
  58.  
    int memtotal;// 存放内存峰值大小
  59.  
    char *ret = fgets (line_buff, sizeof(line_buff), fd);// 读取memtotal这一行的数据,memtotal在第1行
  60.  
    sscanf (line_buff, "%s %d", name, &memtotal);
  61.  
    fprintf (stderr, "====%s:%d====\n", name, memtotal);
  62.  
    fclose(fd);
  63.  
     
  64.  
    // 关闭文件fd
  65.  
    return memtotal;
  66.  
    }

测试文件:

  1.  
    #include "get_mem.h"
  2.  
    int main()
  3.  
    {
  4.  
    int list[1024];
  5.  
     
  6.  
     
  7.  
    for (int i = 0; i < 1024; i++)
  8.  
    {
  9.  
    list[i] = i;
  10.  
    }
  11.  
     
  12.  
    int mem = get_memory_by_pid(getpid());
  13.  
    }