《观察linux行为-实验报告(共11页).doc》由会员分享,可在线阅读,更多相关《观察linux行为-实验报告(共11页).doc(11页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、精选优质文档-倾情为你奉上实验二观察Linux行为实验时间6小时实验目的学习Linux内核、进程、存储和其他资源的一些重要特征。实验目标编写一个程序使用/proc机制检查反映机器平均负载、进程资源利用等方面的各种内核值。在得到内核状态之后,将所观察到的行为在屏幕上输出。背景知识Linux、Solaris和其他版本的UNIX提供了一种非常有用的检查内核状态机制,叫做/proc文件系统。这是可以用来完成本练习的关键机制。1. /proc文件系统/proc文件系统是一种操作系统机制,它的接口就像传统UNIX文件系统的一个目录(在根目录中)。可以改变到/proc正如改变到任何其他目录,例如,bash$
2、 cd /proc使/proc作为当前目录。一旦把/proc作为当前目录,就可以用ls命令列出它的内容。其内容看起来像普通的文件和目录。但是,/proc或者其子目录中的文件实际上是读取内核变量并以ASCII字符串方式报告它们的程序。这些例程中的一些仅在伪文件打开时读取内核表,而其他例程在每次文件被访问时读表。因此各种读函数的工作方式可能与预期的有所不同,因为它们并没有在真正操作文件。Linux提供的/proc实现可以读取很多不同的内核表。/proc中包含一些目录和文件,每个文件读取一个或多个内核变量。而具有数字名称的子目录包括更多的伪文件读取其进程ID和目录名相同的进程的有关信息。self目录
3、包含了正在使用/proc进程的特定进程信息。/proc目录树的确切内容随Linux的版本而不同,所以必须对伪文件进行实验查看所提示的信息。/proc中的文件可以像普通的ASCII文件一样进行读取。例如,向shell敲入以下命令:bash$ cat /proc/version将得到打印到stdout的类似下面的信息:Linux version 2.2.12 (gcc version egcs-2.91.66/Linux (egcs-1.1.2 release) #1 Mon Sep 27 10:40:35EDT 1999为了读取一个伪文件的内容,可以打开文件然后使用stdio程序库中的例程如fg
4、ets()或者fscanf()来读取文件。所读的确切文件(和表)依赖于所使用的特定Linux版本。想要知道到底有些什么文件接口通过/proc对你可用,请查看系统上的proc使用手册页。2使用argc和argv在程序的B部分和C部分,需要从shell向程序传递参数。Linux中,C主程序依然可以采用argc和argv来传递参数。具体用法这里不再赘述。问题陈述1. 编写一个程序,通过检查内核状态报告Linux内核行为。程序在stdout上打印以下信息:l CPU类型和型号。l 内核版本l 从系统最后一次启动以来的时间,形式为dd:hh:mm:ss(例如,3天13小时46分32秒应该写出03:13:
5、46:32)。2. 改写A部分程序,加入命令行参数,在stdout上再打印以下信息:l CPU花费在用户态、系统态和空闲态的时间。l 系统接收到的磁盘请求。l 内核执行的上下文转换的次数。l 系统最后启动的时间。l 从系统启动开始创建的进程数。3. 改写B部分程序,根据不同的命令行参数,在stdout上再打印以下信息:l 计算机配置的内存数量。l 当前可用的内存数量。l 平均负载列表(至上一分钟的平均数)。该信息将使另外的程序可以查看各个时间的这些值,因此用户可以了解平均负载如何随时间间隔而变化。对于本程序,提供两个命令行参数:(1) 一个表明应该以什么样的频率从内核读取平均负载。(2) 一个
6、表明应该以多长的时间间隔读取平均负载。A部分程序可以叫做ksamp,B部分程序ksamp s,C部分程序ksamp l 2 60,表示平均负载观察将运行60秒,每隔2秒取样一次。为了观察系统上的负载,需要确保计算机正在做一些其他的工作而不是仅仅运行你的程序。例如,打开和关闭窗口、移动窗口,甚至在其他窗口运行一些程序。组织方案对于B部分和C部分,程序必须在命令行上有不同的参数。因此最先的动作之一应该是解析调用程序的命令行以确定通过argv数组传递到它的shell参数。可参考如下代码:int main( int argc, char *argv ) char repTypeName16;/ 决定报
7、告类型reportType = STANDARD;strcpy( repTypeName, “Standard” );if ( argc 1) sscanf( argv1, “%c%c”, &c1, &c2 );if ( c1 != “-“ ) fprintf( stderr, “usage: observer -s -l int dur n” );exit(1);if ( c2 = s ) reportType = SHORT;strcpy( repTypeName, “Short” );if ( c2 = l ) reportType = LONG;strcpy( repTypeName,
8、 “Long” );internal = atoi( argv2 );duration = atoi( argv3 );在得到今天的当前时间并打印出一个包含你所检查机器名字的问候之后,就完成了初始化工作。#include / 完成初始化gettimeofday( &now, NULL ); /得到当天时间printf( “Status report type %s at %sn”, repTypeName, ctime( &( now.tv_sec ) ) );/ 得到主机文件名并打印它thisPorcFile = fopen( “/proc/sys/kernel/hostname”, “r”
9、 );fgets( lineBuf, LB_SIZE+1, thisPorcFile );printf( “Machine hostname: %s”, lineBuf );fclose( thisPorcFile );现在可以准备开始工作,也就是说,通过使用各种/proc文件开始读取内核变量。上述代码段包含一个如何读取/proc/sys/kernel/hostname文件的例子。可以用它作为原型通过读取其他的伪文件来完成练习,这需要对/proc进行一些探索以及在研究不同的目录时对各种伪文件进行检查。在C部分中将要计算平均负载。对于这个问题,代码需要睡眠一段时间,醒来后采样当前平均负载,然后再
10、返回睡眠状态。这里是一段可以完成该工作的代码:while( iteration duration) sleep( interval );sampleLoadAvg();iteration += interval;实验步骤1. 在proc文件系统中找出需要读取的文件。2. 设计读取proc文件系统中文件的方法。3. 设计读取某文件指定标识处内容的方法。4. 完成问题陈述A。5. 完成问题陈述B。6. 完成问题陈述C。实验结果1. 实验步骤1的结果是什么?2. 请描述实验步骤2的流程。3. 请描述实验步骤3的流程。4. 请描述实验步骤4的方案。5. 请描述实验步骤5的方案。6. 请描述实验步骤6的
11、方案。实验报告1. 引言Linux 内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构、改变内核设置的机制。 本次实验所讨论的就是利用该机制检查反映机器平均负载、进程资源利用等方面的各种内核值。在得到内核状态之后,将所观察到的行为在屏幕上输出。工作步骤:编写代码查看CPU的配置信息;编写ABC三个代码段完成实验要求。结果:完成了主要代码的编写及运行,实现了实验要求,但是没有进行代码的优化。意义:了解了/proc机制,加深了gcc的使用,对LINUX的更多详细信息有了进一步的了解。2. 问题提出鉴于/proc机制,本实验要解决的问题有:(1) 编写程序在stdout上显示/p
12、roc中文件(CPU的类型和型号,所使用的Linux内核版本,从系统最后一次启动以来已经经历了多长时间);(2) 改写A程序,在stdout上显示CPU花费在用户态、系统态和空闲态的时间、系统接收到的磁盘请求、内核执行的上下文转换的次数、系统最后启动的时间、从系统启动开始创建的进程数;(3) 改写B程序,在stdout上显示计算机配置的内存数量、当前可用的内存数量、平均负载列表(至上一分钟的平均数);(4) 改写C程序,计算平均负载。3. 解决方案3.1 显示/proc中文件程序见附录(1)。3.2 改写ABC三部分程序详见附录(1)(2)(3)。4. 实验结果1. 实验步骤1的结果是:Cpu
13、info version uptime uptime stat diskstats meminfo .2. 步骤2的流程:对于直接显示的文件信息,可以如下方式读取:while(ch!=EOF)printf(“%c”,ch);ch=fgetc(fp);/fp为文件指针,使用fgetc()函数依次读取3. 步骤3的流程:对于需要读取相应参数值的可以用struct数据结构,然后显示相应的值:struct nameChar Int ;然后对应结构体的相应参数读取相应的值,使用fread()函数读取。4. 问题陈述A:首先需要知道所需的信息在哪个文件的哪个位置才可以准确定位,因此打开文件cpuinfo,
14、version,uptime,在读出的文件里定位到需要的信息(CPU型号、内核版本、系统最后一次启动以来的时间),比如CPU型号在cpuinfo里面是第五项,先空读4次,第五次读出的就是CPU型号,打印出来(要注意时间格式),其它几项同理。程序代码见附录(1)。5. 问题陈述B:(1)从文件/proc/stat可以得到CPU花费在用户态、系统态和空闲态的时间;(2)从文件/proc/diskstats可以得到系统接收到的磁盘请求;(3)定位到内核执行的上下文转换的次数; (4)系统最后启动的时间:用localtime函数把从1970-1-1零点零分到当前时间系统所偏移的秒数时间转换为日历时间;
15、(5)定位到从系统启动开始创建的进程数。6. 问题陈述C:(1) 打开文件meminfo;(2) 定位到计算机配置的内存数量;(3)定位到当前可用的内存数量;(4)平均负载列表(至上一分钟的平均数);(5)通过一个while求平均,每次循环先睡眠一段时间,唤醒后采样当前负载,然后再返回睡眠状态。5. 结束语 在实验过程开始时,我查阅了/proc文件系统的相关资料,/proc文件系统提供了一个基于文件的Linux内部接口。老师已在实验要求中给出了一部分程序范例,根据这些前期准备进行了实验。实验过程中。实验目的基本完成,但是代码没有进行优化,可能运行性能比较低。通过本次试验,我了解了Linux内核
16、、进程以及存储的一些重要特征,学习了一些在/proc文件系统中文件操作的函数。6. 附录(1) A部分void func_A()int i,t,d,h,m,s;char c512;FILE * in1,* in2,* in3;in1=fopen(/proc/cpuinfo,r);/打开acpuinfo文件in2=fopen(/proc/version,r);/打开version文件in3=fopen(/proc/uptime,r);/打开auptime文件/获取需要显示的信息for(i=0;itm_year+1900, tp-tm_mon+1,tp-tm_mday,tp-tm_hour,tp-
17、tm_min,tp-tm_sec);/显示系统最后启动时间给用户in1=fopen(/proc/stat,r);in2=fopen(/proc/diskstats,r);/打开文件fscanf(in1,%s %d %d %d %d,&c,&m,&n,&o,&p);/获取所需信息量printf(用户态时间:%d(0.01秒) 系统态时间:%d(0.01秒) 空闲态时间:%d(0.01秒)n,m,o,p);/显示用户态时间、系统态时间、空闲态时间while(fgets(c,512,in2)!=NULL)sscanf(c,%d %d %s %d %d %d %d %d,&m,&m,&d,&o,&m,
18、&m,&m,&p);if(d0=s)printf(系统接收到的磁盘请求 %s:读 %d ,写 %d ,总计%dn,d,o,p,o+p);break;while(fgets(c,512,in1)!=NULL)sscanf(c,%s %d,&d,&m);if(strcmp(d,ctxt)=0)/定位到内核执行的上下文转换的次数printf(上下文转换的次数:%dn,m);if(strcmp(d,processes)=0)/定位到从系统启动开始创建的进程数printf(从系统启动开始创建的进程数:%dn,m);fclose(in1);fclose(in2);fclose(in3);/关闭文件(3)
19、C部分void func_C()FILE *in1,*in2; /定义2个文件指针char c512,d32; /存放信息的数组int t,iteration=0; float m;in1=fopen(/proc/meminfo,r);/打开meminfo文件while(fgets(c,512,in1)!=NULL)sscanf(c,%s %d,&d,&t);if(strcmp(d,MemTotal:)=0)/定位到计算机配置的内存数量printf(计算机配置的内存数量:%dn,t);if(strcmp(d,MemFree:)=0)/定位到当前可用的内存数量printf(当前可用的内存数量:%dn,t);printf(平均负载列表至上一分钟的平均数:n);while(iteration1)sscanf(argv1,%c%c,&c1,&c2);if(c1!=-)printf(usage: observer -s -l int durn);return;if(c2=s)func_B();return;if(c2=l)internal=atoi(argv2);/将string对象转化成int对象duration=atoi(argv3);func_C();return;专心-专注-专业
限制150内