实验二 观察Linux行为,使用proc文件系统
一、实验目的
学习Linux内核、进程、存储和其他资源的一些重要特征。读/proc/stat
文件,计算并显示系统CPU占用率和用户态CPU占用率。(编写一个程序使用/proc
机制获得以及修改机器的各种资源参数。需要使用fopen()
,fscanf()
,printf()
)
二、实验内容
Part A
以超级用户的身份进入/proc
目录,在终端上键入ls命令,察看该目录下的内容,同时察看每个文件的读写权限。
选择一台机器,试着回答下列问题:
-
CPU
的类型和型号。 -
所使用的Linux的版本。
-
从启动到当前时刻经过的时间。
-
内存状态。
Part B
-
编写一个程序,用来获得内核参数(任意的参数均可)。
-
编写一个程序,用来修改内核参数(任意的参数均可)。
三、实验步骤
-
使用man命令了解
/proc/stat
文件的内容和格式:man proc
-
使用man命令了解下列函数的使用方法:
fopen:
// 原型如下 FILE *fopen( const char *filename, const char *mode ); // 以打开一个流(文件)。filename——文件名,mode——访问许可类型。
fscanf
// 原型如下 int fscanf( FILE *stream, const char *format [, argument ]); // 从流中读取格式化的数据。
fclose
// 原型如下: int fclose( FILE *stream ); // 关闭流(文件)。
-
用c语言编程
首先编写主函数,建立程序的基本框架,将实现功能的函数放在头文件
info.h
中#include<stdio.h> #include "func.h" // functions insidevoid extra() {while (1) {printf("Please select from those numbers below:");printf("\n1:CPU INFO\n2:Linux VERSION INFO\n3:SYSTEM TIME INFO\n4:RAM INFO\n5:sumCpuTime\n"); // some attention infoint order = 0; // flagwhile (order = getchar()) {// printf("%d\n", order);switch (order) {case 49:cpuInfo();break;case 50:linuxVersion();break;case 51:sysTime();break;case 52:ramInfo();break;case 53:sumCpuTime();break;}}} } int main(int argc, char *argv[]) {extra();printf("\nCopy that, over!"); }
对于文件
info.h
定义保存文件的字符数组
shell
以及文件指针ptr
char shell[100]; // the order FILE *ptr = NULL; // file ptr
初始化数组
void initShell() {memset(shell, 0, sizeof(shell)); }
初始化文件指针
void initPtr() {ptr = NULL; }
编写函数
linuxVersion()
显示系统信息/** To get info about Linux version and print*/ void linuxVersion() {ptr = fopen("/proc/version", "r"); // open the sourceif (ptr == NULL) {printf("Got nothing");} else {while (1) {if (fgets(shell, 512, ptr) == NULL) { // if the string ended, breakbreak;}printf("Linux version info:%s", shell); // disp the info}fclose(ptr); // close fileinitPtr(); // init pointerinitShell(); // init order array} }
编写函数
cpuInfo()
读取CPU信息/** To get info about CPU and print*/ void cpuInfo() {ptr = fopen("/proc/cpuinfo", "r"); // open the sourceif (ptr == NULL) {printf("Got nothing");} else {while (1) {if (fgets(shell, 512, ptr) == NULL) { // if the string ended, breakbreak;}printf("%s", shell); // disp the info}fclose(ptr);initPtr();initShell();} }
编写函数
sysTime()
读取系统信息首先定义三个宏保存一天、一小时、一分钟等价秒数(其实按照C的编写要求更应该使用
const int
类型变量)#define DAY 86400 #define HOUR 3600 #define MINUTE 60
函数主体如下
/** To get info how long the OS' running time*/ void sysTime() {int t; // t means timeint d, h, m, s; // days, hours, minutes, secondsptr = fopen("/proc/uptime", "r"); // open the sourceif (ptr == NULL) {printf("Got nothing");} else {fscanf(ptr, "%d", &t);// down side here are focusing on format the time we gotd = t / DAY;t = t % DAY;h = t / HOUR;t = t % HOUR;m = t / MINUTE;t = t % MINUTE;s = t;printf("Time info:%02ddays:%02dhours:%02dminutes:%02dseconds\n", d, h, m, s); // disp the info}fclose(ptr);initPtr(); }
编写函数
ramInfo()
读取内存信息/** To get info about ram*/ void ramInfo() {ptr = fopen("/proc/meminfo", "r"); // open the sourceif (ptr == NULL) {printf("Got nothing");} else {while (1) {if (fgets(shell, 512, ptr) == NULL) { // if the string ended, breakbreak;}printf("Ram info:%s", shell); // disp the info}fclose(ptr);initPtr();initShell();} }
编写函数
sumCpuTime()
计算:- 总CPU时间 = 用户占用时间+系统占用时间+优先进程占用时间+闲置进程占用时间
- 系统CPU占用率 = 系统占用时间 / 总CPU时间
- 用户态CPU占用率 = 用户占用时间 / 总CPU时间
void sumCpuTime() {char cpu[10];long user, nice, sys, idle, iowait, irq, softirq, total; // user_using, sys_using,float sys_usage, user_usage;ptr = fopen("/proc/stat", "r");if (ptr == NULL) {printf(("Got nothing"));} else {// only the first line will be usefgets(shell, sizeof(shell), ptr);printf("cpu time info:%s\n", shell);sscanf(shell, "%s%ld%ld%ld%ld%ld%ld%ld", cpu, &user, &nice, &sys, &idle, &iowait, &irq, &softirq);total = user + nice + sys + idle + iowait + irq + softirq; // total timesys_usage = (float)sys / (float)total;user_usage = (float)user / (float)total;printf("总时间:%ld", total);printf("系统使用时间占比:%.3f%\n", sys_usage * 100);printf("用户使用时间占比:%.3f%\n", user_usage * 100);} }
info.h
完整结构如下// // Created by lunatic on 2020/10/17. // #include <string.h> #ifndef HOMEWORK2_FUNC_H #define HOMEWORK2_FUNC_H #define DAY 86400 #define HOUR 3600 #define MINUTE 60char shell[100]; // the order FILE *ptr = NULL; // file ptrvoid initShell() {memset(shell, 0, sizeof(shell)); }void initPtr() {ptr = NULL; }/** To get info about Linux version and print*/ void linuxVersion() {ptr = fopen("/proc/version", "r"); // open the sourceif (ptr == NULL) {printf("Got nothing");} else {while (1) {if (fgets(shell, 512, ptr) == NULL) { // if the string ended, breakbreak;}printf("Linux version info:%s", shell); // disp the info}fclose(ptr); // close fileinitPtr(); // init pointerinitShell(); // init order array} }/** To get info about CPU and print*/ void cpuInfo() {ptr = fopen("/proc/cpuinfo", "r"); // open the sourceif (ptr == NULL) {printf("Got nothing");} else {while (1) {if (fgets(shell, 512, ptr) == NULL) { // if the string ended, breakbreak;}printf("%s", shell); // disp the info}fclose(ptr);initPtr();initShell();} }/** To get info how long the OS' running time*/ void sysTime() {int t; // t means timeint d, h, m, s; // days, hours, minutes, secondsptr = fopen("/proc/uptime", "r"); // open the sourceif (ptr == NULL) {printf("Got nothing");} else {fscanf(ptr, "%d", &t);// down side here are focusing on format the time we gotd = t / DAY;t = t % DAY;h = t / HOUR;t = t % HOUR;m = t / MINUTE;t = t % MINUTE;s = t;printf("Time info:%02ddays:%02dhours:%02dminutes:%02dseconds\n", d, h, m, s); // disp the info}fclose(ptr);initPtr(); }/** To get info about ram*/ void ramInfo() {ptr = fopen("/proc/meminfo", "r"); // open the sourceif (ptr == NULL) {printf("Got nothing");} else {while (1) {if (fgets(shell, 512, ptr) == NULL) { // if the string ended, breakbreak;}printf("Ram info:%s", shell); // disp the info}fclose(ptr);initPtr();initShell();} }void sumCpuTime() {char cpu[10];long user, nice, sys, idle, iowait, irq, softirq, total; // user_using, sys_using,float sys_usage, user_usage;ptr = fopen("/proc/stat", "r");if (ptr == NULL) {printf(("Got nothing"));} else {// only the first line will be usefgets(shell, sizeof(shell), ptr);printf("cpu time info:%s\n", shell);sscanf(shell, "%s%ld%ld%ld%ld%ld%ld%ld", cpu, &user, &nice, &sys, &idle, &iowait, &irq, &softirq);total = user + nice + sys + idle + iowait + irq + softirq; // total timesys_usage = (float)sys / (float)total;user_usage = (float)user / (float)total;printf("total time:%ld", total);printf("percentage of system time:%f%\n", sys_usage * 100);printf("percentage of user time:%f%\n", user_usage * 100);} } #endif //HOMEWORK2_FUNC_H
编写程序,实现一次性查看
/proc
下的多个文件// // Created by Lunatic on 2020/11/25. // #include <stdio.h>int main(int argc, char *argv[]) {char buffer[100];FILE *fp;int i = 1;for (; 1; i++) {if (argc[1] == NULL) {printf("There's no file out there");return 0;}fp = fopen(argv[1], "r");if (fp == NULL) {printf("File could not be opened\n");} else {while (1) {if (fgets(buffer, 100, fp) == NULL) {break;}printf("%s", buffer);}fclose(fp);}}return 0; }
四、实现结果
使用如下命令进行编译,输出一个名为task
的二进制文件
gcc -o task main.c
开始执行
依次测试各功能:
-
CPU INFO
查看CPU信息 -
Linux VERSION INFO
查看Linux
版本信息 -
SYSTEM INFO
查看本机操作系统系统信息 -
RAM INFO
查看内存信息 -
sumCpuTime
查看占用事件 -
输入命令读取多个文件
执行程序,在之后附上命令,查看
Linux
版本信息./a1 /proc/version /proc/cpuinfo
五、实验心得
本次实验学习了在Linux
如何使用Vim
编写程序以及如何调用编译器对编写的程序进行编译。Linux
的文件均存放在/proc
目录下,在用户态下进行编程,使用文件指针读取文件即可查看相关的文件信息。