Linux内核实验(一):proc文件系统

一、引言

Proc文件系统,以文件系统的形式向用户提供系统当前状态,动态地从同内核中读出所需的信息,只存在内存中,不占用外存空间。

二、实验内容

问题A:
1、cpu类型
2、内核版本

问题B:
1、系统启动以来的时间,以dd:hh:mm:ss报告

问题C:
1、cpu执行用户态、系统态、空闲态所用时间
2、多少次磁盘请求
3、多少次上下文切换
4、启动了多少次进程

问题D:
1、内存总量
2、可用内存
3、系统平均负荷

三、实验代码

/*****************************************
*
* Proc 文件系统
*
* Copyright: (C) 2018.3.31 by shaomingshan
*
* Compile: gcc -o main main.c
*
* Execute: ./main -a
*
*****************************************/
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#define LB_SIZE 80

enum TYPE{STANDARD,SHORT,LONG};
FILE *thisProcFile; //Proc 打开文件指针
struct timeval now; //系统时间日期
enum TYPE reportType; //观察报告类型
char repTypeName[16];
char *lineBuf; //proc 文件读出行缓冲
int interval; //系统负荷监测时间间隔
int duration; //系统负荷监测时段
int iteration;
char c1,c2; //字符处理单元

void sampleLoadAvg() { //观察系统负荷
    int i=0;
    //打开负荷文件
    if ((thisProcFile = fopen("/proc/loadavg", "r")) == NULL)
    {
        printf("Open Failed\n");
        return;
    }
    //读出、处理读出行,如去除前导空格和无用空格
    fgets(lineBuf, LB_SIZE+1, thisProcFile);
    char * c3 = strtok(lineBuf, " ");
    //将读出行分出不同字段,按照字段的不同含义处理为可阅读格式
    //打印处理好的信息内容
    while (c3 != NULL) {
        i ++;
        switch (i) {
            case 1:
                printf("1分钟内平均负载: ");
                break;
            case 2:
                printf("5分钟内平均负载: ");
                break;
            case 3:
                printf("15分钟内平均负载: ");
                break;
            case 4:
                printf("活动进程比: ");
                break;
            case 5:
                printf("最近进程号: ");
                break;
        }
        printf("%s\n", c3);
        c3 = strtok(NULL, " ");
    }
    fclose(thisProcFile);
}

void sampleTime() {//观察系统启动时间
    long uptime,idletime;
    int day,hour,minute,second;
    int i,j;
    char temp[80];
    i=j=0;
    //打开计时文件
    //读出、处理读出行,如去除前导空格和无用空格
    thisProcFile = fopen("/proc/uptime", "r");
    fgets(lineBuf, LB_SIZE+1, thisProcFile);
    //将读出行分出不同字段,按照字段的不同含义处理为可阅读格式
    //将启动时间的秒数转换为长整数
    uptime = atol(strtok(lineBuf, " "));
    //转换成日时钟秒
    day = uptime/3600/24;
    hour = uptime/3600%24;
    minute = uptime/60%60;
    second = uptime%60;
    //打印处理好的信息内容
    printf("uptime: %2ldd:%2ldh:%2ldm:%2lds\n",
            day, hour, minute, second);
    //将启动时间的空闲秒数转换为长整数
    idletime = atol(strtok(NULL, " "));
    //转换成日时钟秒
    day = idletime/3600/24;
    hour = idletime/3600%24;
    minute = idletime/60%60;
    second = idletime%60;
    //打印处理好的信息内容
    printf("idletime: %2ldd:%2ldh:%2ldm:%2lds\n",
            day, hour, minute, second);
}

int main(int argc,char *argv[])
{
    lineBuf = (char *)malloc(LB_SIZE+1);
    reportType = STANDARD;
    strcpy(repTypeName,"Standard");
    if(argc >1){
        sscanf(argv[1],"%c%c",&c1,&c2);//取命令行选择符
        if(c1!='-'){ //提示本程序命令参数的用法
            exit(1);
        }
        if(c2 == 'a'){
            //观察部分 A
            printf("**********PART A **********\n");
            reportType = SHORT;
            strcpy(repTypeName,"Short");
            //取出并显示系统当前时间
            //读出并显示机器名
            //读出并显示全部 CPU 信息
            //读出并显示系统版本信息
            thisProcFile = fopen("/proc/cpuinfo", "r");
            while (!feof(thisProcFile)) {
                fgets(lineBuf, LB_SIZE+1, thisProcFile);
                if (strstr(lineBuf, "model name")) {
                    printf("%s", lineBuf);
                    break;
                }
            }
            fclose(thisProcFile);
            system("uname -r");
        }
        else if(c2 == 'b'){
            //观察部分 B
            printf("**********PART B **********\n");
            //打开内存信息文件
            //读出文件全部的内容
            //处理并用方便阅读的格式显示
            //观察系统启动时间
            sampleTime();
        }
        else if(c2 == 'c'){
            //观察部分 C
            printf("**********PART C**********\n");
            //打开系统状态信息文件
            thisProcFile = fopen("/proc/stat", "r");
            //读出文件全部的内容
            //处理并用方便阅读的格式显示
            fgets(lineBuf, LB_SIZE+1, thisProcFile);
            while (!feof(thisProcFile)) {
                char *output = strtok(lineBuf, " ");
                if (!strcmp(output, "cpu")) {
                    int i = 0;
                    while (i < 4) {
                        output = strtok(NULL, " ");
                        switch (i) {
                            case 0:
                                printf("用户态时间: %s\n", output);
                                break;
                            case 1:
                                break;
                            case 2:
                                printf("系统态时间: %s\n", output);
                                break;
                            case 3:
                                printf("空闲态时间: %s\n", output);
                                break;
                        }
                        i++;
                    }
                } else if (!strcmp(output, "intr")) {
                    output = strtok(NULL, " ");
                    printf("磁盘请求: %s\n", output);
                } else if (!strcmp(output, "ctxt")) {
                    output = strtok(NULL, " ");
                    printf("上下文切换: %s\n", output);
                } else if (!strcmp(output, "processes")) {
                    output = strtok(NULL, " ");
                    printf("启动进程数: %s\n", output);
                }
                fgets(lineBuf, LB_SIZE+1, thisProcFile);
            }   
            fclose(thisProcFile);
        }
        else if(c2 == 'd'){
            //观察部分 D
            printf("**********PART D **********\n");
            if(argc<4){
                printf("usage:observer [-b] [-c][-d int dur]\n");
                exit(1);
            }
            thisProcFile = fopen("/proc/meminfo", "r");
            int i = 0;
            // 内存信息文件
            while (i++ < 3) {
                fgets(lineBuf, LB_SIZE+1, thisProcFile);
                strtok(lineBuf, " ");
                char *output = strtok(NULL, " ");
                switch (i) {
                    case 1:
                        printf("总内存: ");
                        break;
                    case 2:
                        printf("空闲内存:");
                        break;
                    case 3:
                        printf("可用内存:");
                }
                printf("%s\n", output);
            }
            fclose(thisProcFile);
            reportType = LONG;
            strcpy(repTypeName,"Long");
            //用命令行参数指定的时间段和时间间隔连续的
            interval = atol(argv[2]);
            duration = atol(argv[3]);
            //读出系统负荷文件的内容用方便阅读的格式显示
            for (int i = 0; i < duration / interval; ++i) {
                sampleLoadAvg();
                // 系统负荷信息
                sleep(interval);
            }
        }
    }
}

四、运行结果

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

如有错误请指正

猜你喜欢

转载自blog.csdn.net/baidu_34045013/article/details/80147742