【操作系统】实验二:观察Linux,使用proc文件系统

发布于:2024-12-18 ⋅ 阅读:(169) ⋅ 点赞:(0)

实验二 观察Linux,使用proc文件系统

实验目的:学习Linux内核、进程、存储和其他资源的一些重要特征。读/proc/stat文件,计算并显示系统CPU占用率和用户态CPU占用率。(编写一个程序使用/proc机制获得以及修改机器的各种资源参数。需要使用fopen(),fscanf(),printf())

2.1 介绍

Linux操作系统提供了一套非常有用的在用户态检查内核状态的机制——/proc文件系统。在该文件系统将 进程的地址空间,系统的硬件信息(包括CUP、内存状态以及网卡等各种硬件设备)以及操作系统系统(中断、IO)等内容全部设置成虚拟的Linux文件——它只存在内存当中,而不占用外存空间。它以文件系统的方式为访问系统内核数据的操作提供接口。

​ /proc 中的每个文件都有一组分配给它的非常特殊的文件许可权,并且每个文件属于特定的用户标识,这里面的文件仅仅包含以下三种权限(除非root用户特别授权):

1. 只读:任何用户都不能更改该文件;它用于表示系统信息;

2. root 写:如果 /proc 中的某个文件是可写的,则通常只能由 root 用户来写;

3. root 读:有些文件对一般系统用户是不可见的,而只对 root 用户是可见的;

4. 其它:出于各种原因,您可能会看到不同于上面常见的三种许可权的组合。

当然,除了/proc/sys目录以外,其余大部分目录下的文件对于root用户是只读的,该目录下存放的是内核参数,并被设计成为运行时刻修改的。

以下列出了/proc文件系统各个子目录的内容:

目录名 内容描述
apm 高级电源管理信息
cmdline 内核命令行
cpuinfo cup信息
devices 可用的设备信息
dma 已经使用的 DMA 管道
filesystems 系统支持的文件系统
interrupts 中断信息
ioports 端口使用信息
kcore 内核核心映像
kmsg 内核消息
ksyms 内核符号表
loadavg 平均负载
locks 内核锁
meminfo 内存信息
misc misc信息
modules 内核加载模块列表
mounts 已加载文件信息
partitions 系统识别的分区表
rtc 实时锁
slab slab 对象池的信息
stat 全面信息统计状态表
swaps 交换分区使用情况
version 内核版本
uptime 系统正常运行时间
sys 内核参数

并不是所有的目录在你的系统中都有,这取决于你内核的配置和装载的模块。另外,/proc目录下还有两个很重要的目录:net和scsi,均依赖于内核的配置。例如,如果你的系统不支持sici设备则sici目录不存在。

除此之外,你还会发现一些以数字命名的目录,它们是进程目录。系统中当前运行的每一个进程都有一个对应的目录在/proc下,以进程的ID号为目录名,他们就是读取进程信息的接口。每个进程目录的结构如下:

子目录名称 包含内容
cmdline 该进程的命令行参数
enviroment 进程换进变量的值
fd 该进程所打开的文件的描述符
mem 该进程的内存使用情况
stat 进程状态
cwd 进程的当前目录
root 进程的根目录
maps 内存映像
statm 进程内存状态信息
exe 当前进程的可执行文件(链接)

​ 如果你要察看系统信息,可以使用cat命令,例如:

# cat /proc/interrupts

CPU0

0: 8728810 XT-PIC timer

1: 895 XT-PIC keyboard

2: 0 XT-PIC cascade

3: 531695 XT-PIC aha152x

4: 2014133 XT-PIC serial

5: 44401 XT-PIC pcnet_cs

8: 2 XT-PIC rtc

11: 8 XT-PIC i82365

12: 182918 XT-PIC Mouse

13: 1 XT-PIC fpu PS/2

14: 1232265 XT-PIC ide0

15: 7 XT-PIC ide1

NMI: 0

前面已经说过,/proc/sys目录不仅提供了内核信息,而且可以通过它修改内核参数。(但是你必须很小心,因为可能会造成系统崩溃。最好是先找一台无关紧要的机子,调试成功后再应用到你的系统上。) 要改变内核的参数,只要用vi编辑或echo参数重定向到文件中即可。下面有一个例子:

# cat /proc/sys/fs/file-max

4096

# echo 8192 > /proc/sys/fs/file-max

# cat /proc/sys/fs/file-max

8192

2.2 实验内容

​ 部分A

以超级用户的身份进入/proc目录,在终端上键入ls命令,察看该目录下的内容,同时察看每个文件的读写权限。

如图所示:

img

选择一台机器,试着回答下列问题:

l CPU的类型和型号。

使用如下命令:cat /proc/cpuinfo | grep “model name”,如图所示:

img

l 所使用的Linux的版本。

使用命令uname -r来查看当前虚拟机的内核版本,如图所示:

img

l 从启动到当前时刻经过的时间。

使用命令uptime来查看从启动到当前时刻经过的时间,如图所示:

img

l 内存状态。

使用命令:cat /proc/meminfo来查看内存状态,如图所示:

img

​ 部分B

l 编写一个程序,用来获得内核参数(任意的参数均可)。

以下是读取内核参数swappiness(用于控制系统的内存管理,特别是交换空间(swap)的使用行为。它的值范围是 0 到 100)的值的代码:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int swappiness;
    FILE *fp;

    // 打开 /proc/sys/vm/swappiness 文件
    fp = fopen("/proc/sys/vm/swappiness", "r");
    if (fp == NULL) {
        perror("fopen");
        return 1;
    }

    // 读取 swappiness 值
    fscanf(fp, "%d", &swappiness);
    fclose(fp);

    printf("现在的swappiness值为: %d\n", swappiness);
    return 0;
}

我创建了一个getparameter.c 的文件,使用命令gcc -o getparameter getparameter.c命令来编译这个C语言文件,在使用./getparameter指令来执行上述C语言文件,执行之后的结果如下:

img

l I 编写一个程序,用来修改内核参数(任意的参数均可),现在我们编了一个可以更改swappiness(低值(如 10-20): 适用于需要高性能的场景,例如游戏或实时应用。这种情况下,系统会尽量保留数据在物理内存中,以提高访问速度;高值(如 60-80): 适用于服务器或需要长时间运行的应用,尤其是在内存较小的情况下。这样可以更好地利用交换空间,避免因内存不足导致的应用崩溃)的代码,我们选择将swappiness的值修改为10,代码如下:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int new_swappiness = 10; // 设置新的 swappiness 值
    FILE *fp;

    // 打开 /proc/sys/vm/swappiness 文件进行写入
    fp = fopen("/proc/sys/vm/swappiness", "w");
    if (fp == NULL) {
        perror("fopen");
        return 1;
    }

    // 写入新的 swappiness 值
    fprintf(fp, "%d", new_swappiness);
    fclose(fp);

    printf("Swappiness的值被设置为: %d\n", new_swappiness);
    return 0;
}

执行之后,如图所示:

img

此时,swappiness的值就成功的修改为了10。

2.3 实验步骤

1) 使用man命令了解/proc/stat文件的内容和格式:

man proc

如图所示:

img

2) 使用man命令了解下列函数的使用方法:

fopen:

命令:man fopen

原型:FILE *fopen( const char *filename, const char *mode );

以打开一个流(文件)。filename——文件名,mode——访问许可类型。

如图所示:

img

fscanf:

命令:man fscanf

原型:int fscanf( FILE *stream, const char *format [, argument ]… );

从流中读取格式化的数据。

例子fscanf (fp ,“cpu %ld”, &user)是指跳过字符串"cpu "及其前面的字符流,读取一个长整数并存入user中。其中fp为文件流指针。%ld对应长整数,%d对应整数,%s对应字符串。

如图所示:

img

fclose:

命令:man fclose

原型:int fclose( FILE *stream );

关闭流(文件)。

如图所示:

img

3)用c语言编程

总CPU时间 = 用户占用时间+系统占用时间+优先进程占用时间+闲置进程占用时间

系统CPU占用率 = 系统占用时间 / 总CPU时间

用户态CPU占用率 = 用户占用时间 / 总CPU时间

代码如下:

#include <stdio.h>
#include <unistd.h>
 
unsigned long long get_cpu_time() {
    unsigned long long user, nice, system, idle;
    // 读取/proc/stat文件中的CPU时间信息
    FILE* file = fopen("/proc/stat", "r");
    fscanf(file, "cpu %llu %llu %llu %llu", &user, &nice, &system, &idle);
    fclose(file);
    return user + nice + system + idle;
}
int main() {
    unsigned long long prev_total_time = 0, prev_user_time = 0;
    double system_cpu_usage, user_cpu_usage;
    while (1) {
        // 获取当前的CPU时间信息
        unsigned long long total_time = get_cpu_time();
        unsigned long long user_time = total_time - get_cpu_time();
        // 计算系统CPU占用率和用户态CPU占用率
        if (prev_total_time != 0) {
            system_cpu_usage = (double)(total_time - prev_total_time - (user_time - prev_user_time)) / (total_time - prev_total_time);
            user_cpu_usage = (double)(user_time - prev_user_time) / (total_time - prev_total_time);
 
            printf("系统CPU占用率:%.2f%%\n", system_cpu_usage * 100);
            printf("用户态CPU占用率:%.2f%%\n", user_cpu_usage * 100);
        }
 
        prev_total_time = total_time;
        prev_user_time = user_time;
 
        sleep(1);  // 每隔1秒钟更新一次CPU时间信息
    }
 
    return 0;
}

4)编译和运行

使用命令vim CpuInfo.c创建一个C语言文件,将上述的代码复制进去

使用命令gcc -o CpuInfo CpuInfo.c编译此C语言文件

使用命令./CpuInfo运行此文件,结果如图所示:

img

2.4 实验总结

1.在本次实验中,我深入探索了Linux的proc文件系统,了解其在系统监控和管理中的重要性。proc文件系统以虚拟文件的形式提供了内核和进程的信息,位于 /proc 目录下。通过读取这些文件,我能够获取系统的实时状态,包括CPU使用率、内存占用、进程信息等。

2.使用命令如 cat /proc/cpuinfocat /proc/meminfo,我获取了详细的CPU和内存信息,帮助我理解系统资源的分配情况。此外,/proc/[pid]/status 文件让我能够查看特定进程的状态和资源使用情况,增强了我对进程管理的理解。

3.通过对proc文件系统的观察,我认识到其在系统调试和性能监控中的关键作用。这次实验不仅提升了我对Linux内核的理解,也为后续的系统优化和故障排查打下了基础。未来,我希望能进一步研究proc文件系统的其他功能,如进程调度和内核参数调整。


网站公告

今日签到

点亮在社区的每一天
去签到