🕺作者: 主页
我的专栏 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权限
 注意事项:
- 不要随便修改内核参数,可能会导致机器出现莫名的问题
 提高的能力:
- 编码能力有待提高
- 对命令的熟悉度有待提高


















