汇总 花了哥100多个金币啊 Linux内核编程实验报告.docx
- 文档编号:8690900
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:91
- 大小:1.56MB
汇总 花了哥100多个金币啊 Linux内核编程实验报告.docx
《汇总 花了哥100多个金币啊 Linux内核编程实验报告.docx》由会员分享,可在线阅读,更多相关《汇总 花了哥100多个金币啊 Linux内核编程实验报告.docx(91页珍藏版)》请在冰豆网上搜索。
汇总花了哥100多个金币啊Linux内核编程实验报告
Linux内核分析实验报告
实验题目:
观察Linux行为
实验目的:
学习Linux内核,进行横,存储和其他资源的一些特征。
硬件环境:
内存1G以上
软件环境:
Linux(Ubuntu)2-6
实验步骤:
一:
实验原理:
1.Proc文件简介:
Proc文件系统是一个为文件系统,只存在于内存当中,而不占用外存空间,它是由内核在内存中产生的。
它以文件系统的方式为访问系统内核数据的操作提供接口。
用户和应用程序可以通过proc得到系统的信息,并且可以修改某一些参数。
由于系统的信息,如进程,是动态改变的,所以用户或者应用程序读取proc文件时,proc文件系统是动态从系统内核中读取所需要的信息并且提交的。
2.本实验中所需要信息。
1、cpu的类型与型号
/proc/cpuinfo
2、所使用的Linux内核版本
/proc/version
3、从系统最后一次启动以来已经经历了时间
/proc/stat(btime)
/proc/uptime这个好像也可以,没有求证哦:
(
4、总共有多少cpu时间执行在用户态?
系统态?
空闲态?
/proc/stat第一行第一个域是用户态时间,
第二个是低优先权用户模式时间,
第三个是系统态时间,
第四个是空闲态时间。
5、配置了多少内存?
当前多少可用?
/proc/meminfo
6、有多少磁盘读写请求
/proc/diskstats
7、内核已经进行了多少次上下文切换?
/proc/stat ctxt域
8、从系统启动以来已经创建了多少进程?
/proc/stat proccesses域
9、平均负载
/proc/loadavg
实验体会:
明白了proc文件的机制,初步了解了Linux内核的一些东西
#include
#include
#include
#include
#defineLB_SIZE80
enumTYPE{STANDARD,SHORT,LONG};
FILE*thisProcFile;//Proc打开文件指针
structtimevalnow;//系统时间日期
enumTYPEreportType;//观察报告类型
charrepTypeName[16];
char*lineBuf;//proc文件读出行缓冲
intinterval;//系统负荷监测时间间隔
intduration;//系统负荷监测时段
intiteration;
char**word;
charc1,c2;//字符处理单元
chartemp[10][80];
voidsampleLoadAvg(){//观察系统负荷
inti,j;
i=j=0;//打开负荷文件
printf("******打开负荷文件loadavg**********\n");
thisProcFile=fopen("/proc/loadavg","r");
if(thisProcFile==NULL)
{
printf("Can'topenfile!
\n");
exit(0);
}
for(i=0;i<5;i++)
{
fscanf(thisProcFile,"%s",temp[i]);
}
printf("1分钟内的平均进程数为:
%s\n",temp[0]);
printf("5分钟内的平均进程数为:
%s\n",temp[1]);
printf("15分钟内的平均进程数为:
%s\n",temp[2]);
i=0;
while
(1)
{
if(temp[3][i]=='/')
break;
i++;
printf("%d\n",i);
//sleep
(1);
}
printf("正在运行的进程数为:
");
for(j=0;j
printf("%c",temp[3][j]);
printf("\n");
//sleep(11);
j=j+1;
printf("总进程数为:
");
while(temp[3][j]!
=0)//不能是NULL
{
printf("%c",temp[3][j]);
j++;
}
printf("\n");
printf("最近运行的进程ID号为:
%s\n",temp[4]);
fclose(thisProcFile);
}
voidsampleTime(){//观察系统启动时间
longuptime,idletime;
intday,hour,minute,second;
inti,j;
i=j=0;
//打开计时文件...
//读出、处理读出行,如去除前导空格和无用空格...
//将读出行分出不同字段,按照字段的不同含义处理为可阅读格式...
//打印处理好的信息内容„...
//将启动时间的秒数转换为长整数...
//转换成日时钟秒...
//将启动时间的空闲秒数转换为长整数...
//转换成日时钟秒...
//打印处理好的信息内容...}
thisProcFile=fopen("/proc/stat","r");
if(thisProcFile==NULL)
{
printf("Can'topenfile!
\n");
exit
(1);
}
for(i=0;i<10;i++)
{
fscanf(thisProcFile,"%s",temp[i]);
}
printf("从系统启动开始累计到当前时刻,用户态的CPU时间(单位:
jiffies):
%s\n",temp[1]);
printf("从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间(单位:
jiffies):
%s\n",temp[2]);
printf("从系统启动开始累计到当前时刻,核心时间(单位:
jiffies):
%s\n",temp[3]);
printf("从系统启动开始累计到当前时刻,除硬盘IO等待时间以外其它等待时间(单位:
jiffies):
%s\n",temp[4]);
printf("从系统启动开始累计到当前时刻,硬盘IO等待时间(单位:
jiffies):
%s\n",temp[5]);
printf("从系统启动开始累计到当前时刻,硬中断时间(单位:
jiffies):
%s\n",temp[6]);
printf("从系统启动开始累计到当前时刻,软中断时间(单位:
jiffies):
%s\n",temp[7]);
while(feof(thisProcFile)==0)
{
fgets(lineBuf,LB_SIZE+1,thisProcFile);
if(strstr(lineBuf,"btime")!
=NULL)
{sscanf(lineBuf,"%*s%s",lineBuf);//?
?
?
?
?
?
?
?
uptime=atol(lineBuf);
break;
}
}
idletime=atol(temp[4]);
day=uptime/(60*60*24);
uptime=uptime%(60*60*24);
hour=uptime/(60*60);
uptime=uptime%(60*60);
minute=uptime/60;
second=uptime%60;
printf("启动时间为:
%d日%d小时%d分%d秒\n",day,hour,minute,second);
day=idletime/(60*60*24);
uptime=idletime%(60*60*24);
hour=idletime/(60*60);
uptime=idletime%(60*60);
minute=idletime/60;
second=idletime%60;
printf("空闲时间为:
%d日%d小时%d分%d秒\n",day,hour,minute,second);
fclose(thisProcFile);
}
intmain(intargc,char*argv[])
{
lineBuf=(char*)malloc(LB_SIZE+1);
reportType=STANDARD;
strcpy(repTypeName,"Standard");
inti=0;
if(argc>1){
sscanf(argv[1],"%c%c",&c1,&c2);//取命令行选择符
if(c1!
='-'){
fprintf(stderr,"usage:
ksamp[-s][-lintdur]\n");//提示本程序命令参数的用法
exit
(1);}
if(c2=='b'){//观察部分B
printf("******PARTB**********\n");
//打开内存信息文件„
//读出文件全部的内容„
//处理并用方便阅读的格式显示...
printf("******内存文件内容**********\n");
thisProcFile=fopen("/proc/meminfo","r");
if(thisProcFile==NULL)
{
printf("Can'topenfile!
\n");
exit
(1);
}
while(fgets(lineBuf,LB_SIZE+1,thisProcFile)!
=NULL)
{
printf("%s",lineBuf);
}
fclose(thisProcFile);
//观察系统启动时间
printf("******观察系统时间结果**********\n");
sampleTime();
}
elseif(c2=='c'){//观察部分C
printf("******PARTC**********\n");
//打开系统状态信息文件„
//读出文件全部的内容„
//处理并用方便阅读的格式显示...
printf("******打开系统状态信息文件stat**********\n");
thisProcFile=fopen("/proc/stat","r");//打开stat文件
if(thisProcFile==NULL)
{
printf("Can'topenfile!
\n");
exit
(1);
}
for(i=0;i<10;i++)
{
fscanf(thisProcFile,"%s",temp[i]);
}
printf("从系统启动开始累计到当前时刻,用户态的CPU时间(单位:
jiffies):
%s\n",temp[1]);
printf("从系统启动开始累计到当前时刻,核心时间(系统态时间)(单位:
jiffies):
%s\n",temp[3]);
printf("从系统启动开始累计到当前时刻,除硬盘IO等待时间以外其它等待时间(空闲时间)(单位:
jiffies):
%s\n",temp[4]);
while(feof(thisProcFile)==0)
{
fgets(lineBuf,LB_SIZE+1,thisProcFile);
if(strstr(lineBuf,"ctxt")!
=NULL)
{sscanf(lineBuf,"%*s%s",lineBuf);//?
?
?
?
?
?
?
?
从一行中取特定字符串
printf("上下文切换次数%s",lineBuf);
printf("\n");
break;
}
}
while(feof(thisProcFile)==0)
{
fgets(lineBuf,LB_SIZE+1,thisProcFile);
if(strstr(lineBuf,"processes")!
=NULL)
{sscanf(lineBuf,"%*s%s",lineBuf);//?
?
?
?
?
?
?
?
printf("从系统开始创建进程数%s",lineBuf);
printf("\n");
break;
}
}
fclose(thisProcFile);
//打开diskstats文件
printf("******打开文件diskstat**********\n");
thisProcFile=fopen("/proc/diskstats","r");//打开diskstat文件
if(thisProcFile==NULL)
{
printf("Can'topenfile!
\n");
exit
(1);
}
while(feof(thisProcFile)==0)
{
fgets(lineBuf,LB_SIZE+1,thisProcFile);
if(strstr(lineBuf,"sda")!
=NULL)
{//for(i=0;i<10;i++)
sscanf(lineBuf,"%*s%*s%*s%s%*s%*s%*s%s",temp[i],temp[i+1]);
//指针从发现出开始?
?
?
?
?
strstr返回的是一个比较字符相等处的指针,但lineBuf内容是那行内容,即(strstr(lineBuf,"sda")返回的是地址
break;
}
}
printf("读磁盘数:
%s\n",temp[i]);
printf("写磁盘数:
%s\n",temp[i+1]);
fclose(thisProcFile);
}
elseif(c2=='d'){//观察部分D
intm=0;
printf("******PARTD**********\n");
if(argc<4){
printf("usage:
observer[-b][-c][-dintdur]\n");
exit
(1);}
reportType=LONG;
strcpy(repTypeName,"Long");
//用命令行参数指定的时间段和时间间隔连续的
duration=atoi(argv[2]);
printf("您输入的时间段为%d\n",duration);
interval=atoi(argv[3]);
printf("您输入的时间间隔为%d\n",interval);
//读出系统负荷文件的内容用方便阅读的格式显示
while(iteration { sleep(interval); sampleLoadAvg(); iteration+=interval; } printf("******获取内存信息**********\n"); thisProcFile=fopen("/proc/meminfo","r"); if(thisProcFile==NULL) { printf("Can'topenfile! \n"); exit (1); } for(m=0;m<2;m++) { fgets(lineBuf,LB_SIZE+1,thisProcFile); printf("%s\n",lineBuf); } } else{//观察部分A printf("******PARTA**********\n"); reportType=SHORT; strcpy(repTypeName,"Short"); //取出并显示系统当前时间 printf("******获取当前时间**********\n"); gettimeofday(&now,NULL); printf("Statusreporttype%sat%s\n",repTypeName,ctime(&(now.tv_sec))); printf("******获取机器名**********\n"); thisProcFile=fopen("/proc/sys/kernel/hostname","r"); if(thisProcFile==NULL) { printf("Can'topenfile! \n"); exit (1); } fgets(lineBuf,LB_SIZE+1,thisProcFile); printf("机器名为: %s\n",lineBuf); fclose(thisProcFile); printf("******获取全部CPU信息**********\n"); thisProcFile=fopen("/proc/cpuinfo","r"); if(thisProcFile==NULL) { printf("Can'topenfile! \n"); exit (1); } while(fgets(lineBuf,LB_SIZE+1,thisProcFile)! =NULL) { printf("%s",lineBuf);//不需加\n,文件中有换行符,也同时度进来了 } printf("******获取全部CPU版本信息**********\n"); thisProcFile=fopen("/proc/version","r"); if(thisProcFile==NULL) { printf("Can'topenfile! \n"); exit (1); } while(fgets(lineBuf,LB_SIZE+1,thisProcFile)! =NULL) { printf("%s",lineBuf);//不需加\n,文件中有换行符,也同时度进来了 } fclose(thisProcFile); } } } Linux内核分析实验报告 实验题目: shell编程 实验目的: 学习如何编写一个Linuxshell程序,使得有机会了解如何创建子进程来执行一项专门的工作以及父进程如何继续子进程的工作 硬件环境: 内存1G以上 软件环境: Linux(Ubuntu)2-6 实验步骤: 一: 实验原理简介 用户输入一个字符串数组。 第一步: shell程序分析出其中的各个参数,将参数分别存储在argv1和argv2字符串数组中(运用编译原理中的自动机实现),并分析其中动作类型标识符(管道,重定向等);第二步: 创建子进程,调用系统函数execvp函数,运行相应的指令。 重定向输出: 将标准输出换为指定的文件。 close (1)指令关闭,当前进程的标准输出文件。 即切断stdout文件与描述符为1的文件的关联。 然后用open函数打开指定文件,得到文件描述符file1,调用dup函数将1号文件描述符指向目标输出,file1任务完成,close(file1),使得指向目标文件的文件描述符仅仅是1号文件描述符。 调用execvp运行指定程序,执行结果输入到指定文件之中。 (见图2--1) (2--1) 重定向输入: 同理。 管道: 申请一个管道,创建两个子进程。 子进程1将标准输出换为管道的写端,子进程2将标准输入换为管道的读端,执行相应的指令,结果输出。 (见图2--2) (图2--2) 后台执行: 结尾以&结尾的指令,shell不用等待子进程执行完,因此wait()操作没有必要。 在这里,在子进程中又创建了一个子进程(孙子进程),然后把孙子进程的父进程杀掉,如此,孙子就由init进程负责清理,因此,就做到了后台处理得目的。 (见图2--3) (图2--3) 同时处理多条指令: 创建两个子进程,分别执行在argv1和argv2中的参数,得到结果,输出到标准输出屏幕上。 (见图2--4) (图2--4) 二: 主要函数介绍 1: 系统调用函数 (1)intexecvp(constchar*file,char*constargv[]); 函数说明: execvp()会查找符合参数file的文件名,找到后便执行该文件,然后将第二个参数argv传给该欲执行的文件。 (2)intdup(intfiledes); 函数说明: dup返回新文件描述符是当前可用的为您教案描述符的最小数值。 (3)intclose(intfiledes); 函数说明: 关闭一个打开的文件,输入参数是文件描述符。 (4)intaccess(constchar*pathname,intmode); 函数说明: 判断文件pathname是否存在 2: 自定义函数: (1)Char*orderpath(char*name); 函数说明: 在环境变量的目录中,逐个对name文件名进行配对,如果配对成功返回文件的绝对路径。 三: 结果检测: (1)管道 (正确) (2)重定向输出 、 此时文件jieguo中的内容是 (正确) (3)同时执行两条指令 (正确) (4)后台执行 (正确) 结论分析与体会: shell是用户程序与系统内核交互的窗口,用户程序通过这样一个程序,可以方便地实现操作系统接口的调用。 本次实验中,我的感受是自己一些基本的shell指令不是很熟悉,但是通过这个实验,加深了对管道,重定向的机制的运用。 这对理解Linux内核是有很大帮助的。 附: 程序源代码 /******************************************************************* myshell.c-description ------------------- copyright: (C)2002by Function: shell,&,<,>,| I/O ********************************************************************/ #include #include #include #include #defineLB_SIZE80 #defineLS80 FILE*file1,*file2; char*lineBuf,*tempBuf,*filename; enumfangshi{PIPE,ORIENT_input,ORIENT_output,NORMAL,BACK,MUL}; char*env[]={"/usr/local/sbin/","/usr/local/bin/","/usr/sbin/","/usr/bin/","/sbin/","/bin/","/usr/
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 汇总 花了哥100多个金币啊 Linux内核编程实验报告 100 金币 Linux 内核 编程 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)