😘欢迎关注:👍点赞🙌收藏✍️留言
🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要,有问题可在评论区提出,感谢支持!!!
实验二
实验内容
- 实验名称:Proc文件系统
- 实验目的:学习Linux内核、进程、存储和其他资源的一些重要特征。读/proc/stat文件,计算并显示系统CPU占用率和用户态CPU占用率。(编写一个程序使用/proc机制获得以及修改机器的各种资源参数。需要使用fopen(),fscanf(),printf())
- 实验任务:学习和掌握proc文件系统的功能、工作原理及其应用
实验过程
- 以超级用户的身份进入/proc目录,在终端上键入ls命令,察看该目录下的内容,同时察看每个文件的读写权限,如图1所示。
图1 查看/proc目录 - 选择一台机器,试着回答下列问题:
CPU的类型和型号,如图2所示。
图2 查看CPU型号
所使用的Linux的版本,如图3所示。
图3 查看Linux版本
从启动到当前时刻经过的时间,如图4所示。
图4 查看时间
内存状态,如图5所示。
图5 查看内存状态
3. 编码
- 编写一个程序,用来获得内核参数(任意的参数均可)。
- 编写一个程序,用来修改内核参数(任意的参数均可)。
两个任务我放到一个程序中,既可以获取参数又可以修改参数,由于内核参数太过重要不敢轻易修改,所以我找到网络信息最大连接数来修改,这样就不会太过影响机器,获取当前的网络信息最大连接数并修改它:
网络信息的最大连接数是一个相对概念,它取决于使用的网络设备和协议。在计算机网络中,最大连接数通常指的是某个网络设备(如路由器、交换机、防火墙等)所能同时支持的最大连接数,如图6所示。
图6 查看最大连接数
代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define MAX_BUF_SIZE 256 int get_max_connections() { FILE *fp; char buf[MAX_BUF_SIZE]; int max_connections; // 打开/sys文件系统中的内核参数文件 fp = fopen("/proc/sys/net/core/somaxconn", "r"); if (fp == NULL) { perror("打开文件失败"); return -1; } // 读取最大连接数 fgets(buf, sizeof(buf), fp); // 转换为整数 max_connections = atoi(buf); // 关闭文件 fclose(fp); return max_connections; } int set_max_connections(int max_connections) { FILE *fp; // 打开/sys文件系统中的内核参数文件 fp = fopen("/proc/sys/net/core/somaxconn", "w"); if (fp == NULL) { perror("打开文件失败"); return -1; } // 将最大连接数写入文件 fprintf(fp, "%d", max_connections); // 关闭文件 fclose(fp); return 0; } int main() { int max_connections; // 获取当前最大连接数 max_connections = get_max_connections(); if (max_connections == -1) { return 1; } printf("当前最大连接数: %d\n", max_connections); // 修改最大连接数为新的值 if (set_max_connections(1000) == -1) { return 1; } printf("最大连接数已修改为: 1000\n"); return 0; }
- 使用man命令了解/proc/stat文件的内容和格式,如图7所示。
man proc
图7 查看man命令 - 使用man命令了解下列函数的使用方法,如图8~10所示。
fopen:
原型:FILE *fopen( const char *filename, const char *mode );
以打开一个流(文件)。filename——文件名,mode——访问许可类型。
图8 查看fopen
fscanf:
原型:int fscanf( FILE *stream, const char *format [, argument ]… );
从流中读取格式化的数据。
例子fscanf (fp ,“cpu %ld”, &user)是指跳过字符串"cpu "及其前面的字符流,读取一个长整数并存入user中。其中fp为文件流指针。%ld对应长整数,%d对应整数,%s对应字符串。
图9 查看fscanf
fclose:
原型:int fclose( FILE *stream );
关闭流(文件)。
图10 查看fclose
用c语言编程,如图11所示。
总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时间信息 total_time = get_cpu_time(); 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; }
编译和运行
图11 运行程序显示结果
实验小结
问题:
1.在修改内核参数的时候发现很多都不能修改,需要root权限
注意事项:
- 不要随便修改内核参数,可能会导致机器出现莫名的问题
提高的能力: - 编码能力有待提高
- 对命令的熟悉度有待提高