学习Linux内核、进程、存储和其他资源的一些重要特征。读/proc/stat
文件,计算并显示系统CPU占用率和用户态CPU占用率。(编写一个程序使用/proc
机制获得以及修改机器的各种资源参数。需要使用fopen()
,fscanf()
,printf()
)
以超级用户的身份进入/proc
目录,在终端上键入ls命令,察看该目录下的内容,同时察看每个文件的读写权限。
选择一台机器,试着回答下列问题:
CPU
的类型和型号。
所使用的Linux的版本。
从启动到当前时刻经过的时间。
内存状态。
编写一个程序,用来获得内核参数(任意的参数均可)。
编写一个程序,用来修改内核参数(任意的参数均可)。
使用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 inside
void 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 info
int order = 0; // flag
while (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 source
if (ptr == NULL) {
printf("Got nothing");
} else {
while (1) {
if (fgets(shell, 512, ptr) == NULL) { // if the string ended, break
break;
}
printf("Linux version info:%s", shell); // disp the info
}
fclose(ptr); // close file
initPtr(); // init pointer
initShell(); // init order array
}
}
编写函数cpuInfo()
读取CPU信息
/*
* To get info about CPU and print
*/
void cpuInfo() {
ptr = fopen("/proc/cpuinfo", "r"); // open the source
if (ptr == NULL) {
printf("Got nothing");
} else {
while (1) {
if (fgets(shell, 512, ptr) == NULL) { // if the string ended, break
break;
}
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 time
int d, h, m, s; // days, hours, minutes, seconds
ptr = fopen("/proc/uptime", "r"); // open the source
if (ptr == NULL) {
printf("Got nothing");
} else {
fscanf(ptr, "%d", &t);
// down side here are focusing on format the time we got
d = 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 source
if (ptr == NULL) {
printf("Got nothing");
} else {
while (1) {
if (fgets(shell, 512, ptr) == NULL) { // if the string ended, break
break;
}
printf("Ram info:%s", shell); // disp the info
}
fclose(ptr);
initPtr();
initShell();
}
}
编写函数sumCpuTime()
计算:
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 use
fgets(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 time
sys_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 60
char shell[100]; // the order
FILE *ptr = NULL; // file ptr
void 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 source
if (ptr == NULL) {
printf("Got nothing");
} else {
while (1) {
if (fgets(shell, 512, ptr) == NULL) { // if the string ended, break
break;
}
printf("Linux version info:%s", shell); // disp the info
}
fclose(ptr); // close file
initPtr(); // init pointer
initShell(); // init order array
}
}
/*
* To get info about CPU and print
*/
void cpuInfo() {
ptr = fopen("/proc/cpuinfo", "r"); // open the source
if (ptr == NULL) {
printf("Got nothing");
} else {
while (1) {
if (fgets(shell, 512, ptr) == NULL) { // if the string ended, break
break;
}
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 time
int d, h, m, s; // days, hours, minutes, seconds
ptr = fopen("/proc/uptime", "r"); // open the source
if (ptr == NULL) {
printf("Got nothing");
} else {
fscanf(ptr, "%d", &t);
// down side here are focusing on format the time we got
d = 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 source
if (ptr == NULL) {
printf("Got nothing");
} else {
while (1) {
if (fgets(shell, 512, ptr) == NULL) { // if the string ended, break
break;
}
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 use
fgets(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 time
sys_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
目录下,在用户态下进行编程,使用文件指针读取文件即可查看相关的文件信息。