🕺作者: 主页
我的专栏 C语言从0到1 探秘C++ 数据结构从0到1 探秘Linux 😘欢迎关注:👍点赞🙌收藏✍️留言
🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要,有问题可在评论区提出,感谢支持!!!
文章目录
- 实验二
- 实验内容
- 实验过程
- 实验小结
实验二
实验内容
-
实验名称: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权限
注意事项:
- 不要随便修改内核参数,可能会导致机器出现莫名的问题
提高的能力: - 编码能力有待提高
- 对命令的熟悉度有待提高