一、引言
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);
}
}
}
}
四、運行結果
如有錯誤請指正