操作系统课程设计报告_第1页
操作系统课程设计报告_第2页
操作系统课程设计报告_第3页
操作系统课程设计报告_第4页
操作系统课程设计报告_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、操作系统课程设计报告 任务1:I/O系统调用开销比较任务5:实现一个malloc/free学院:计算机科学与工程学院专业:信息安全班级:2班姓名:学号:指导老师:二一一年三月六日目录任务一:I/O系统调用开销比较 21.1 实验目的21.2 任务要求21.3 实验原理21.4 实现过程21.5 程序测试 41.6 源代码4任务五:实现一个malloc/free 52.1 实验目的52.2 任务要求52.3 实验原理52.4 实现过程52.4.1 主要函数52.4.2 调试中出现的错误以及改进方法8 2.4.3 程序测试82.5 源代码8心得体会9附表110附表213任务一:I/O系统调用开销比

2、较一、 实验目的在于了解I/O系统调用的特点并通过性能测试对此有直观的认识。二、 任务要求在LINUX平台用C编程逆序一个文本文件,注意显示逆序结果的必须是原文件名。如文件原内容为“abcd”,处理后内容应为“dcba”。请分别使用三种方法:标准C的I/O库函数:fopen,fread和fwriteUnix 的I/O函数:open.read 和writeOpen 和mmap 要求尽量考虑效率,比较三种方法的性能。三、 实验原理(1)在标准C下,利用fopen函数打开“renwu11”的文件和一个“fan”的文件,并声明两个指针,一个读文件指针fp1,一个写入文件指针fp2,用fseek函数进行

3、来定位光标,然后一边读入size,一边逆序写出size,逆序完毕后,然后用 rename函数对“fan”进行重命名,任务就完成!(2)Unix与标准C下,思路是一样的,只是函数的运用不同!(3)Mmap存储映射,将文件的内容映射到进程地址空间,利用open函数打开文件,mmap在内存中开辟地址,其返回值为最后文件映射到进程空间的地址,声明两个int类型的参数,mmap的返回值赋值给int参数,然后在内存中首位地址交换,完成文件的逆序,然后释放空间,完成任务!四、实现过程Fangfa1.c程序:首先声明程序入口为3个参数,分别为程序编译后文件名,读字节的大小size,需逆序文件的大小。如有错误,

4、则提示。if(argc !=3)printf(Usage:%s n,argv0);exit(EXIT_FAILURE) 分别fopen文件,如文件为空,则提示错误,并退出函数。Fseek函数来定位,从最后开始读,每次读size个if(fseek(fp1,-size,SEEK_END)0)printf(fseek errorn);exit(EXIT_FAILURE) 然后边读入,边逆序写入if(fread(buffer,size,1,fp1)0)for(i=0;isize/2;i+)ch=bufferi;bufferi=buffersize-i-1;buffersize-i-1=ch;if(fw

5、rite(buffer,size,1,fp2)0)最后关闭文件,重命名函数rename(fan, argv2);(2) fangfa2.c程序思路与fangfa1.c基本一样,不过函数的头文件不一样,程序也基本相同,只是函数的运用不同而已,详细见源代码!(3) fangfa3.c程序:首先声明程序入口为3个参数,分别为程序编译后文件名,读字节的大小size,需逆序文件的大小。如有错误,则提示。if(argc !=3)printf(Usage:%s n,argv0);exit(EXIT_FAILURE) 分别fopen文件,如文件为空,则提示错误,并退出函数。利用fstat()函数和ftrunc

6、ate()函数,fatat()来返回已打开的文件信息,ftruncate()的作用是将文件截断到给定的长度size,if(fstat(fp1,&statbuf)0)printf(fstat source errorn);exit(EXIT_FAILURE)if(ftruncate(fp2,statbuf.st_size)0)/ftruncate()会将参数fp2指定的文件大小改为参数length指定的大小printf(ftruncate source errorn);exit(EXIT_FAILURE);然后判断mmap函数是否在内存中映射成功 if(s_fp1=mmap(NULL,size,

7、PROT_READ,MAP_SHARED,fp1,0)=MAP_FAILED)循环逆转size_t i;char *ch1=s_fp1+size-1;char *ch2=s_fp2;for(i=1;iUnix标准C六、源代码见附表1任务五:实现一个malloc/free一、 实验目的实现一个简单的存储管理器,对进程地址空间的管理有进一步的了解。二、 任务要求实现一个malloc/free,设计测试实例,与libc的malloc实现进行性能比较,并分析其实现过程。 三、 实验原理malloc()是C语言中动态存储管理的一组标准库函数之一。其作用是在内存的动态存储区中分配一个长度为size的连续空

8、间。其参数是一个无符号整形数,返回值是一个指向所分配的连续存储域的起始地址的指针。malloc()工作机制:malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。调用free函数时,它将用户释放的内存块连接到空闲链上。到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以

9、满足用户要求的片段了。于是,malloc函数请求延时,并开始在空闲链上检查各内存片段,对它们进行整理,将相邻的小空闲块合并成较大的内存块。四、 实现过程1.主要函数在大部分操作系统中,内存分配由以下函数来处理:void *malloc (long numbytes):该函数负责分配 numbytes 大小的内存,并返回指向第一个字节的指针。void free(void *firstbyte):如果给定一个由先前的 malloc 返回的指针,那么该函数会将分配的空间归还给进程的“空闲空间”。malloc_init 将是初始化内存分配程序的函数。它要完成以下三件事:将分配程序标识为已经初始化,找到

10、系统中最后一个有效内存地址,然后建立起指向我们管理的内存的指针。这三个变量都是全局变量首先,初始化:int has_initialized = 0;void *managed_memory_start;void *last_valid_address;int code_size = 0;在很多linux系统中,为了指出当前系统中断点,必须使用 sbrk(0) 函数。 sbrk 根据参数中给出的字节数移动当前系统中断点,然后返回新的系统中断点。使用参数 0 只是返回当前中断点。 为了完全地管理内存,我们需要能够追踪要分配和回收哪些内存。在对内存块进行了 free 调用之后,我们需要做的是诸如将它

11、们标记为未被使用的等事情,并且,在调用 malloc 时,我们要能够定位未被使用的内存块。因此, malloc 返回的每块内存的起始处首先要有这个结构:内存控制块结构定义struct mem_control_block int is_available; int size;当程序调用 malloc 时,在返回指针之前,我们会将其移动到这个结构之后,把它隐藏起来。这使得返回的指针指向没有用于任何其他用途的内存。那样,从调用程序的角度来看,它们所得到的全部是空闲的、开放的内存。然后,当通过 free() 将该指针传递回来时,我们只需要倒退几个内存字节就可以再次找到这个结构分配内存上,主要使用连接的

12、指针遍历内存来寻找开放的内存块Malloc ( long numbytes )void *current_location;struct mem_control_block *current_location_mcb;void *memory_location; /Which we will returnif(!has_initialized) malloc_init();numbytes += sizeof(struct mem_control_block);code_size = numbytes;printf(nMalloc actually %ld bytes.n,numbytes);

13、memory_location = 0;current_location = managed_memory_start;while(current_location != last_valid_address) printf(an); current_location_mcb = (struct mem_control_block *)current_location; if(current_location_mcb - is_available) if(current_location_mcb - size = numbytes) current_location_mcb - is_avai

14、lable = 0; memory_location = current_location; break; current_location += current_location_mcb - size;if(!memory_location) /往后移动系统中断点numbytes的位置 sbrk(numbytes); memory_location = last_valid_address; last_valid_address += numbytes; current_location_mcb = memory_location; current_location_mcb - is_ava

15、ilable = 0; current_location_mcb - size = numbytes;memory_location += sizeof(struct mem_control_block);#ifdef DEBUG/给内存块填充预设值,测试版本为填充99memset(memory_location,99,(current_location_mcb - size - sizeof(struct mem_control_block);#endifreturn memory_location;为了释放内存,我们必须要做的惟一一件事情就是,获得我们给出的指针,回退 sizeof(str

16、uct mem_control_block) 个字节,并将其标记为可用的。内存的释放使用了一个非常简单的机制,在固定时间内完成内存释放。这里是对应的代码:void free(void *firstbyte) struct mem_control_block *mcb; mcb = firstbyte - sizeof(struct mem_control_block); mcb-is_available = 1;printf(nMalloc free successfully.n);主函数的实现:int main ( int argc, char *argv ) int *p; p = (in

17、t *)Malloc ( 5 * sizeof(int) ); if ( p=NULL ) fprintf ( stderr, ndynamic memory allocation failedn ); Free (p);return 1;2.调试中出现的错误以及改进的方法逐步设计完程序,进行调试过程中遇到了很多错误,例如指针返回值类型,结构体存储内存分配信息,回收内存等等。通过查找相关资料等才得以解决。这里略举一二个错误。首先我不知道sbrk函数的应用,从而找不到当前系统中断点位置,在分配内存上根本无法实现。后来通过找资料得知,sbrk 根据参数中给出的字节数移动当前系统中断点,然后返回新的

18、系统中断点。使用参数 0 只是返回当前中断点。还有,给内存释放空间时候,没有考虑到这样简单的表示方法mcb = firstbyte - sizeof(struct mem_control_block)。3.程序测试程序测试结果:Malloc actually 28 bytes. Malloc free successfully.程序运行成功,申请的分配内存空间为4*5=20bytes,再加上存储分配信息的那部分结构体所占空间8bytes,总共28bytes五、源代码 见附表2心得体会在这次长达两个礼拜的操作系统的课程设计中,通过做任务,来巩固自己的学习的知识,强化自己的动手实践能力,在任务完成

19、过程中,遇到了不少的问题,由于平常动手少,所以刚开始几天难以动手,并且学的知识不够牢,许多程序函数的运用都记不起来,又重新去查找资料,构思程序的结构。通过这次操作系统的课程设计实验,使我明白在做电脑方面学习时一定要多动手才能更好的学好自己的专业。当然理论基础要学好,不过在学好这个的基础上面我们还应该多动手操作,这样,我们才能更好的提高自己。另外一个方面,我们也应该要学会查找资料,不应该只是能做什么,而更多的是知道怎样去学习,当今互联网上学习知识甚多,我们要学会去如何利用。虽然我对学习计算机的兴趣不是很浓厚,但是我愿意去接受更多的知识来充实自己,我跨专业考研,但是我也不会落下本专业要学的东西,但

20、不会钻的很深,也就拓展一下自己的知识面。虽然这次课程设计完成的不是很理想,但是还是感谢胡老师以及帮助过我的同学,让我或多或少的学到了某些方面的知识。 附表1:任务一代码方法一:/标准C语言#include#include#include#define SIZE (1024*16)/SIZE分别为1B、256B、4KB、16KBvoid myreverse(char * pBuff, int num)/逆序内存数据int i=0;char ch = a;for (i=0; i num/2; +i)ch = pBuffi;pBuffi = pBuffnum-i-1;pBuffnum-i-1 = c

21、h;int main (void)FILE *fp = NULL;/文件指针int return_val = 0;/文件指针定位测试返回值int filesize = 0;/文件大小char *pBuff1 = NULL;/分配的内存空间指针char *pBuff2 = NULL;int i = 0;int n = 0;/文本数据的SIZE大小块数/open文件if (NULL = (fp = fopen(/home/user/ypf/abc1.txt, r+)printf(Open file error !n);exit(-1);/文件位置指针置于文件末尾,使测文件大小if (0 != (r

22、eturn_val = fseek(fp, -1, SEEK_END)printf(Error about fseek!n);fclose(fp);exit(-1);/测文件大小if (0 = (filesize = ftell(fp)printf(The file content is null !n);fclose(fp);exit(-1);elseprintf(The filesize is %d!n, filesize);/分配两相同内存块(?未解决?关于分配内存的大小问题)if (NULL = (pBuff1 = (char *)malloc(2*SIZE) )printf(Insu

23、fficient memory available !n);fclose(fp);exit(-1);if (NULL = (pBuff2 = (char *)malloc(2*SIZE) )printf(Insufficient memory available !n);fclose(fp);exit(-1);/逆转文本n = filesize/SIZE;for (i=0; in/2; +i)fseek(fp, SIZE*i, SEEK_SET);fread(pBuff1, 1, SIZE, fp);/正向读文件数据块myreverse(pBuff1, SIZE);fseek(fp, -(SI

24、ZE*(i+1)-1, SEEK_END);fread(pBuff2, 1, SIZE, fp);/反向读文件数据块myreverse(pBuff2, SIZE);fseek(fp, SIZE*i, SEEK_SET);fwrite(pBuff2, 1, SIZE, fp);/正向写文件数据块fseek(fp, -(SIZE*(i+1)-1, SEEK_END);fwrite(pBuff1, 1, SIZE, fp);/反向写文件数据块fseek(fp, SIZE*(n/2), SEEK_SET);fread(pBuff1, 1, filesize-SIZE*n, fp);myreverse(

25、pBuff1, filesize-SIZE*n);/逆转中间剩余部分数据fseek(fp, SIZE*(n/2), SEEK_SET);fwrite(pBuff1, 1, filesize-SIZE*n, fp);fclose(fp);free(pBuff1);free(pBuff2);return 0;方法二:/Unix的I/O函数#include#include#include#include#include#include#define SIZE (1024*16)/SIZE分别为1B、256B、4KB、16KBvoid myreverse(char * pBuff, int num)/

26、逆序内存数据int i=0;char ch = a;for (i=0; i (fd = open(abc2.txt, O_RDWR)perror(Open:);exit(-1);/测文件大小if (-1 = (filesize = lseek(fd, -1, SEEK_END)perror(Lseek:);close(fd);exit(-1);elseprintf(The filesize is %d!n, filesize);/分配两相同内存块(?未解决?关于分配内存的大小问题)if (NULL = (pBuff1 = (char *)malloc(2*SIZE) )printf(Insuf

27、ficient memory available !n);close(fd);exit(-1);if (NULL = (pBuff2 = (char *)malloc(2*SIZE) )printf(Insufficient memory available !n);close(fd);exit(-1);/逆转文本n = filesize/SIZE;for (i=0; in/2; +i)lseek(fd, SIZE*i, SEEK_SET);read(fd, pBuff1, SIZE);/正向读文件数据块myreverse(pBuff1, SIZE);lseek(fd, -(SIZE*(i+1

28、)-1, SEEK_END);read(fd, pBuff2, SIZE);/反向读文件数据块myreverse(pBuff2, SIZE);lseek(fd, SIZE*i, SEEK_SET);write(fd, pBuff2, SIZE);/正向写文件数据块lseek(fd, -(SIZE*(i+1)-1, SEEK_END);write(fd, pBuff1, SIZE);/反向写文件数据块lseek(fd, SIZE*(n/2), SEEK_SET);read(fd, pBuff1, filesize-SIZE*n);myreverse(pBuff1, filesize-SIZE*n

29、);/逆转中间剩余部分数据lseek(fd, SIZE*(n/2), SEEK_SET);write(fd, pBuff1, filesize-SIZE*n);close(fd);free(pBuff1);free(pBuff2);return 0;方法三:/open和mmap#include#include#include#include#include#includeint main(void)int fd;char * mp;struct stat statbuf;long int filesize;int i, n;char temp;if (0 (fd = open(abc3.txt

30、, O_RDWR)perror(Open sourse );exit(EXIT_FAILURE);if (0 fstat(fd, &statbuf)perror(fstat source );close(fd);exit(EXIT_FAILURE);filesize = statbuf.st_size;if (MAP_FAILED = (mp = mmap(0, filesize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0) )perror(mmap sourse );close(fd);exit(EXIT_FAILURE);printf(The file

31、size is %dn, filesize-1);n = (filesize-1)/2;for (i=0; in; +i)temp = mpi;mpi = mpfilesize-i-2;mpfilesize-i-2 = temp;close(fd);return 0;附表2:任务五代码#include #include #include #define DEBUGint has_initialized = 0; /找到当前中断点并初始化变量:void *managed_memory_start;void *last_valid_address;int code_size = 0;struct

32、mem_control_block int is_available; int size;/* - function malloc_init - */void malloc_init ( )/malloc_init 将是初始化内存分配程序的函数。它要完成三件事:将分配程序标识为已经初始化,找到系统中最后一个有效内存地址,然后建立起指向我们管理的内存的指针。last_valid_address = (void *)sbrk(0);/从OS中找到最后一个有效地址managed_memory_start = last_valid_address;/我们还没有安排任何的内存使用has_initiali

33、zed = 1;/初始化成功并开始/* - function Free - */void Free (void *firstbyte ) /如果给定一个由先前的 malloc 返回的指针,那么该函数会将分配的空间归还给进程的“空闲空间”。struct mem_control_block *mcb;mcb=firstbyte-sizeof(struct mem_control_block); /获得给出的指针,回退 sizeof(struct mem_control_block) 个字节,并将其标记为可用的mcb-is_available=1;printf(nFree bytes: %dn,mc

34、b-size);if(mcb - size = code_size) printf(The malloc bytes = code size. Free OK.n);else printf(Free Error.n); /* - function Malloc - */void* Malloc (long numbytes ) /该函数负责分配 numbytes 大小的内存,并返回指向第一个字节的指针。void *current_location;struct mem_control_block *current_location_mcb;void *memory_location; /Which we will returnif(!has_initialized) malloc_init();numbytes += sizeof(struct mem_control_block);code_size

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论