下载

1下载券

加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 可变分区分配与回收——采用最坏算法,操作系统课程设计

可变分区分配与回收——采用最坏算法,操作系统课程设计.doc

可变分区分配与回收——采用最坏算法,操作系统课程设计

我是苗苗可
2017-09-27 0人阅读 举报 0 0 暂无简介

简介:本文档为《可变分区分配与回收——采用最坏算法,操作系统课程设计doc》,可适用于综合领域

哈尔滨理工大学课 程 设 计(操作系统)题 目: 可变分区分配与回收采用最坏算法     班 级:计算机科学与技术学院计算机系 班姓 名:   张兢 指导教师:    高雪瑶系主任:    林克正 年月日一、课程设计目的、背景主存是CPU可直接访问的信息空间合理而有效的使用贮存将在很大程度上影响整个计算机系统的性能。本课题要求模拟实现分区式主存管理机制。模拟实现各种分区管理方法以及相应的主存分配以及回收算法。、目的通过该课题进一步加深对可变分区存储机制的理解。加深对存储器动态分区分配算法的认识。掌握“首次适应算法”、“下次适应算法”、“最佳适应算法发”、“最坏适应算法”的内存分配过程。掌握内存的回收策略。二、课题任务描述、设计可用的内存空闲空间并能动态输入用户作业所需的内存大小。、编程模拟各种分配算法的实施过程允许自行选择如“首次适应算法”、“下次适应算法”、“最佳适应算法发”、“最坏适应算法”等常用算法要求实现不少于三种算法。、实现内存的回收。要求考虑回收时的内存合并问题。三、课题研发相关知识(包含所用库函数的介绍)、首次适应算法(firstfit)FF算法要求空闲分区链以地址递增的次序链接。在分配内存时从链首开始顺序查找直至找到一个大小能男足要求的空闲分区位置然后再按照作业的大小从该分区中划出一块内存空间分配给请求者余下的空闲分区仍留在空闲链中。若从链首直至链尾都不能找到一个能满足要求的分区则此次内存分配失败返回。但是低址部分不断被划分会留下许多难以利用的很小的空闲分区。、最佳适应算法(bestfit)所谓“最佳”是指每次为作业分配内存时总是把能满足要求、又是最小的空闲分区分配给作业避免“大材小用”。为了加速寻找该算法要求将所有的空闲分区按其容量以从小到大的顺序形成一空闲分区链。这样第一次找到的能满足要求的空闲区必然是最佳的。这样在存储器中会留下许多难以利用的小空闲区。、最坏适应算法(worstfit)要扫描整个空闲分区表或链表总是挑选一个最大的空闲区分割给作业使用其优点是可使剩下的空闲区不至于太小产生碎片的几率最小对中小作业有力查找效率很高。但是它会使存储器中缺乏大的空闲分区。、回收内存当进程运行完毕释放内存时系统根据会收取的首址从空闲区链中找到相应的插入点并考虑回收区前后是否有空闲分区如果有则把两个分区合并成一个大的空闲分区。、库函数的介绍)stdio就是指“standardbufferedinputoutput"意思就是说带缓冲的标准输入输出!所以了用到标准输入输出函数时就要调用这个头文件!)Stdlibh即standardlibrary标准库文件。Stdlib头文件里包含了C,C语言的最常用的系统函数。Stdlibh里面定义了五中类型一些宏和通用工具函数。类型例如:sizet,wchart,divt,ldivt,lldivt宏例如:EXITFALIRE,EXITSUCCESS,RANDMAX和MBCURMAX。  以下是一些常用的函数:dec置基数为相当于"d"hex置基数为相当于"X"oct置基数为相当于"o"setw(n)设域宽为n个字符四、课题设计:总体结构、所使用的数据结构、主要功能的流程图、程序的技术路线、总体结构 本系统采用了首次适应算法、最佳适应算法和最坏适应算法模拟存储器动态分区。系统利用其中某种分配算法从空闲分区链中找到满足请求内存大小的分区并分配内存给作业。假设总的内存大小为size作业请求的内存大小为request,内存碎片最小为f。当request>size时内存溢出出现系统错误当request<=size时在内存中根据上述算法寻找最佳的内存分区分配给作业。寻找到合适的内存分区之后如果sizerequest<=f,将此分区上的内存全部分配给作业如果sizerequest>f就在此分区上分割request大小的内存给作业剩余内存继续留在当前的分区中。当进程运行完毕系统找到该进程并释放其内存根据所释放内存的位置对内存进行合并。系统流程图:如图图系统框架图:如图图、数据结构()定义的全局变量:#defineSIZE   内存初始大小#defineMINSIZE   碎片最小值enumSTATE{Free,Busy}枚举类型记录分区是否空闲的状态量()定义的结构体:structsubAreaNode。记录分区的主要数据。()函数)voidintSubArea():分配初始分区内存。)intfirstFit(inttaskId,intsize):首次适应算法实现函数taskId为作业名size为作业申请的内存大小。)intbestFit(inttaskId,intsize):最佳适应算法实现函数taskId为作业名size为作业申请的内存大小。)intworstFit(inttaskId,intsize):最坏适应算法实现函数taskId为作业名size为作业申请的内存大小。)intfreeSubArea(inttaskId):内存回收函数该函数主要用于实现内存的回收根据回收内存的位置对分区进行合并操作。其中taskId为所需回收内存的作业号。)voidshowSubArea():显示空闲分区链情况。包括起始地址空间大小。工作状态。作业号。)intmain():主函数主要用于显示操作界面调用各个子函数等功能。、主要功能的流程图()首次适应算法Firstfit(int,int)流程图(图)N()最佳适应算法Bestfit(int,int)流程图(图)图N()最坏适应算法Worstfit(int,int)流程图(图)Y程序的技术路线  本程序采用C语言编写在windows下的VisualC中编译模拟可变分区存储管理方式的内存分配与回收。假定系统的最大内存空间为kb判断是否划分空闲区的最小限值为MINSIZE=。初始化用户可占用内存区的首地址为大小为B。定义一个结构体及其对象subHead实现内存的分配回收及分配表和空闲表的登记。用最佳分配算法实现动态分配时调用intbestFit(inttaskId,intsize)内存分配函数设定循环条件查找最佳空闲分区根据找到的空闲区大小和作业大小判断是整个分配给作业还是切割空闲区后再分配给作业并在“内存分配表”和“空闲分区表”中作登记。调用intfreeSubArea(inttaskId)函数实现内存的回收。顺序循环“内存分配表”找到要回收的作业设置标志位flag当flag=时表示回收成功。回收内存时需考虑内存的种合并方式即合并上下分区、合并上分区、合并下分区、上下分区都不合并。五、带有详细注解的源程序#include<stdioh>#include<timeh>#include<stdlibh>#defineSIZE    内存初始大小#defineMINSIZE    碎片最小值enumSTATE{Free,Busy}staticintss=,ee=structsubAreaNode{intaddr       起始地址intsize       分区大小inttaskId      作业号STATEstate      分区状态 subAreaNode*pre   分区前向指针 subAreaNode*nxt   分区后向指针}subHead初始化空闲分区链voidintSubArea(){分配初始分区内存subAreaNode*fir=(subAreaNode*)malloc(sizeof(subAreaNode))给首个分区赋值  fir>addr =  fir>size =SIZE  fir>state =Free  fir>taskId=  fir>pre  =subHead  fir>nxt  =  初始化分区头部信息  subHeadpre=  subHeadnxt=fir}首次适应算法intfirstFit(inttaskId,intsize){  subAreaNode*p=subHeadnxt while(p!=) { if(p>state==Freep>size>=size){    找到要分配的空闲分区      if(p>sizesize<=MINSIZE){        整块分配        p>state=Busy        p>taskId=taskId      }else{        分配大小为size的区间        subAreaNode*node=(subAreaNode*)malloc(sizeof(subAreaNode))        node>addr=p>addrsize        node>size=p>sizesize        node>state=Free        node>taskId=        修改分区链节点指针        node>pre=p        node>nxt=p>nxt        if(p>nxt!=){          p>nxt>pre =node        }        p>nxt=node        分配空闲区间        p>size=size        p>state=Busy        p>taskId=taskId      }      printf("内存分配成功!n")      return    }    p=p>nxt  }  printf("找不到合适的内存分区分配失败n")  return}最佳适应算法intbestFit(inttaskId,intsize){ subAreaNode*tar=  inttarSize=SIZE  subAreaNode*p=subHeadnxt  while(p!=)  {  寻找最佳空闲区间   if(p>state==Freep>size>=sizep>size<tarSize){      tar=p      tarSize=p>size    }    p=p>nxt  }  if(tar!=){    找到要分配的空闲分区    if(tar>sizesize<=MINSIZE){        整块分配        tar>state=Busy        tar>taskId=taskId      }else{        分配大小为size的区间        subAreaNode*node=(subAreaNode*)malloc(sizeof(subAreaNode))        node>addr=tar>addrsize        node>size=tar>sizesize        node>state=Free        node>taskId=        修改分区链节点指针        node>pre=tar        node>nxt=tar>nxt        if(tar>nxt!=){          tar>nxt>pre =node        }        tar>nxt=node        分配空闲区间        tar>size=size        tar>state=Busy        tar>taskId=taskId      }      printf("内存分配成功!n")      return  }else{    找不到合适的空闲分区    printf("找不到合适的内存分区分配失败n")    return  }}intworstFit(inttaskId,intsize){  subAreaNode*tar=  inttarSize  intmm=  subAreaNode*p=subHeadnxt  while(p!=mm==)  {  寻找最佳空闲区间    if(p>state==Freep>size>=size){      tar=p      tarSize=p>size      mm=    }    else      p=p>nxt  }  p=subHeadnxt  while(p!=)  {    寻找最大空闲区间    if(p>state==Free p>size>=tarSizep>size>=size){      tar=p      tarSize=p>size遍历找到最大空闲区间      p=p>nxt    }   else     p=p>nxt  }  if(tar!=){    找到要分配的空闲分区    if(tar>sizesize<=MINSIZE){        整块分配        tar>state=Busy        tar>taskId=taskId      }else{        分配大小为size的区间       subAreaNode*node=(subAreaNode*)malloc(sizeof(subAreaNode))        node>addr=tar>addrsize        node>size=tar>sizesize        node>state=Free        node>taskId=        修改分区链节点指针        node>pre=tar        node>nxt=tar>nxt        if(tar>nxt!=){          tar>nxt>pre =node        }        tar>nxt=node       分配空闲区间        tar>size=size        tar>state=Busy        tar>taskId=taskId      }      printf("内存分配成功!n")      return  }else{    找不到合适的空闲分区    printf("找不到合适的内存分区分配失败n")    return  }}回收内存intfreeSubArea(inttaskId){  intflag=  subAreaNode*p=subHeadnxt,*pp  while(p!=)  {    if(p>state==Busyp>taskId==taskId){     flag=      if((p>pre!=subHeadp>pre>state==Free)        (p>nxt!=p>nxt>state==Free)){        情况:合并上下两个分区        先合并上区间        pp=p        p=p>pre        p>size=pp>size        p>nxt=pp>nxt        pp>nxt>pre=p        free(pp)        后合并下区间        pp=p>nxt        p>size=pp>size        p>nxt=pp>nxt        if(pp>nxt!=){          pp>nxt>pre=p        }        free(pp)      }elseif((p>pre==subHead||p>pre>state==Busy)        (p>nxt!=p>nxt>state==Free)){        情况:只合并下面的分区        pp=p>nxt        p>size=pp>size        p>state=Free        p>taskId=        p>nxt=pp>nxt        if(pp>nxt!=){          pp>nxt>pre=p        }        free(pp)      }elseif((p>pre!=subHeadp>pre>state==Free)        (p>nxt==||p>nxt>state==Busy)){        情况:只合并上面的分区        pp=p        p=p>pre        p>size=pp>size        p>nxt=pp>nxt        if(pp>nxt!=){          pp>nxt>pre=p        }        free(pp)      }else{        情况:上下分区均不用合并        p>state=Free        p>taskId=      }    }    p=p>nxt  }  if(flag==){    回收成功    printf("内存分区回收成功n")    return  }else{    找不到目标作业回收失败    printf("找不到目标作业内存分区回收失败n")    return  }}*intstart(inttask){  clockts  s=(int)clock()  returns}intend(inttask){  clockts  s=(int)clock()  returns}*显示空闲分区链情况voidshowSubArea(){  printf("*********************************************n")  printf("**    当前的内存分配情况如下:    **n")  printf("*********************************************n")  printf("**起始地址|空间大小|工作状态|作业号**n")  subAreaNode*p=subHeadnxt  while(p!=)  {    printf("****n")    printf("**")    printf("d k |",p>addr)    printf("d k |",p>size)    printf(" s|",p>state==Free"Free":"Busy")    if(p>taskId>){      printf("d ",p>taskId)    }else{     printf("    ")    }    printf("**n")    p=p>nxt  }  printf("*********************************************n")}intmain(){ intoption,ope,taskId,size  初始化空闲分区链  intSubArea()  选择分配算法l:while()  {    printf("**********************n")    printf("请选择要模拟的分配算法:n表示首次适应算法n表示最佳适应算法n表示最坏适应算法n退出n")    printf("**********************n")    scanf("d",option)    system("cls")    if(option==){      printf("你选择了首次适应算法下面进行算法的模拟n")      break    }elseif(option==){      printf("你选择了最佳适应算法下面进行算法的模拟n")      break    }elseif(option==){      printf("你选择了最坏适应算法下面进行算法的模拟n")      break    }    elseif(option==){      exit()    }    else{      printf("错误:请输入nn")    }  }  模拟动态分区分配算法  while()  {    printf("n")    printf("*********************************************n")    printf("  :分配内存n  :回收内存n  :返回上一级菜单n  :退出nn")    printf("*********************************************n")    scanf("d",ope)      system("cls")    if(ope==)break    if(ope==){      模拟分配内存      printf("请输入作业号:")      scanf("d",taskId)      printf("请输入需要分配的内存大小(KB):")      scanf("d",size)      if(size<=){        printf("错误:分配内存大小必须为正值n")        continue      }      调用分配算法      if(option==){        firstFit(taskId,size)     }elseif(option==){        bestFit(taskId,size)      }      else         worstFit(taskId,size)      显示空闲分区链情况      showSubArea()    }elseif(ope==){      模拟回收内存      printf("请输入要回收的作业号:")      scanf("d",taskId)      freeSubArea(taskId)      显示空闲分区链情况      showSubArea()    }elseif(ope==){      gotol    }    else{      printf("错误:请输入n")    }  }  printf("分配算法模拟结束n")  return}六、运行与测试(调试通过的程序主要测试用例和运行界面截图)  测试数据:预设总的内存大小为k。选择首次适应算法分别输入作业号及作业的大小(k),(,k),(,k),(k)然后回收作业和作业,最后退出系统。运行截图如下:主界面:图  图选择首次适应算法:图     图    利用首次适应算法分配内存:图     图回收内存:图                   图                  退出系统:图                   图七、收获及改进意见  每一次的实践都会有很大的收获。做这个题目的时候就针对此题要解决的几个问题反复思考重新翻开教科书把相关内容特别是算法原理认真细致的看了一遍设想会遇到的问题。在内存动态分配程序设计中最佳适应算法比首次要难一些要加上对分配后该分区是否能最好地利用的判断。再一个问题是回收时候的合并对地址的修改不是很有把握。着手写程序后半天才理清回收的内存和上下邻合并的条件与关系写此处的代码时逻辑上比较混乱反复错误反复修改了很多次才调试正确这也是花了最多时间才得以正确实现的部分。之前大多用的c语言对结构体对象等知识淡忘了很多这一次的实践让我找回了很多学过的知识点也弥补了很多的不足之处。逻辑思维也得到了锻炼写代码也不再像初学的时候那么繁琐自己都能感觉到那一点点的进步顿时也觉得充实起来。还有一个难点就是为作业找到最佳空闲区此处是参照了一些资料后理清了条件然后用一个while()两个if()语句循环嵌套就实现了此功能。实践中也发现自身很多的不足比如上理论课时认为已经理解了的算法原理在用代码实践时发现还是有模糊和思考不周的地方。  学习着收获着并快乐着这真是我的感触。对于自身不足的地方我也有了比较清晰的认识对未来的发展也有了个参照将遇到的困难一个个跨过并最终完成此次课程设计真的感觉很有收获很有成就感。动手能力也得到了提高当然我的设计还有很多的不足之处有些问题没能很好解决但通过不断学习和实践我一定会做的更好。  题目 进程软中断通信.题目的主要研究内容及预期达到的目标    实现进程的软中断通信:父进程发信号控制子程序的终止。.题目研究的工作基础或实验条件()硬件环境:Linux平台。()软件环境:标准C语言。.设计思想    系统调用fork()创建两个子进程,再调用signal()让父进程捕    捉键盘上的中断信号(即按CtrlC键)当捕捉到中断信号后,    父进程调用Kill()向两个子进程发出信号,子进程捕捉到信号    后分别输出下列信息后终止:     ChildProcessisKilledbyParent!     ChildProcessisKilledbyParent!  父进程等待两个子进程终止后,输出如下的信息后终止:      ParentProcessisKilled!.流程图    .主要程序代码    #include"stdioh"    #include"unistdh"    #include"signalh"    #include"systypesh"    #include"stdlibh"    intk=    intp,p  pidtchild=,child=    voidfuncfather(intsig) 父进程信号处理函数    {     传送参数sig指定的信号给参数pid指定的进程返回值::成功:出错     信号宏名:SIGUSR用户定义信号信号值:默认动作:终止进程       kill(p,SIGUSR)       kill(p,SIGUSR)    }    voidfuncp(intsig) 子进程p信号处理函数    {  k=  标志相应SIGUSR消息结束}    voidfuncp(intsig) 子进程p信号处理函数    {  k=  标志相应SIGUSR消息结束}    intmain()    {       while((p =fork())==) fork()=创建子进程失败       if(p>) 父进程继续创建子进程p       {         while((p=fork())==)         if(p>)父进程         {        设置信号处理方式依照参数signum指定的信号编号设置处理函数        指定信号到达时跳转到参数handler指定的函数执行        返回值:成功:返回先前信号处理函数指针出错:SIGERR()          signal(SIGINT,funcfather)          wait()  等待子进程结束          wait()  等待子进程结束          printf("Parentprocessiskilled!n")          exit()         }        else  子进程p        {           signal(SIGINT,SIGIGN)  忽略本应给父进程的按键中断          signal(SIGUSR,funcp)接收父进程的消息后转到处理函数          k=          while(k==)  等待子进程收到父进程的消息后置k=          printf("ChildProcessisKilledbyParent!n")          exit()        }        }        else  子进程p       {        signal(SIGINT,SIGIGN)忽略本应给父进程的按键中断        signal(SIGUSR,funcp)接收父进程的消息后转到处理函数        k=        while(k==)  等待子进程收到父进程的消息后置k=        printf("ChildProcessisKilledbyParent!n")        exit()        }        return      }.运行结果及分析        当按下CtrlC后产生消息响应。.心得体会    通过本次实验掌握了如何创建进程以及进程的软中断。题目 进程的管道通信.题目的主要研究内容及预期达到的目标    实现进程的管道通信。.题目研究的工作基础或实验条件()硬件环境:Linux平台。()软件环境:标准C语言。.设计思想    使用系统调用pipe()建立一条管道线两个子进程P和P分    别向管道各写一句话:     MessagefromChildl!     MessagefromChild!   父进程从管道中读出来自于两个子进程的信息,显示在屏幕上。     要求父进程先接收子进程P的消息,再接收子进程P的消息。.流程图    .主要程序代码    #include<unistdh>    #include<signalh>    #include<stdioh>    intpid,pidpidtpid,pid    main()    {      intfd 打开文件的文件描述符数组fd读fd写      charoutpipe,inpipe      pipe(fd) 先创建管道再创建子进程      while((pid=fork())==) fork()=创建子进程失败      if(pid==) Child      {       lockf(fd,,) 建立互斥文件锁       sprintf(outpipe,"MessagefromChildl!") 把串放入数组outpipe中       write(fd,outpipe,)把outpipe所指内存写入个字节到fd的文件       sleep()    *自我阻塞秒*       lockf(fd,,) 解除互斥文件锁       exit()      }      else pid>      {       while((pid=fork())==)       if(pid==) Child       {       lockf(fd,,) *互斥*       sprintf(outpipe,"MessagefromChild!")       write(fd,outpipe,)       sleep()       lockf(fd,,)       exit()       }       else pid>pid>,父进程       {       wait() *同步*       read(fd,inpipe,) *从管道中读长为字节的串*       printf("sn",inpipe)       wait()       read(fd,inpipe,)        printf("sn",inpipe)        exit()       }      }}.运行结果及分析        父进程先接收子进程的消息再接受子进程的消息并打印。.心得体会    通过本次实验掌握了如何创建管道以及利用管道方式进程间通信。题目 进程间通信设计.题目的主要研究内容及预期达到的目标    利用消息队列实现进程间的通信。.题目研究的工作基础或实验条件()硬件环境:Linux平台。()软件环境:标准C语言。.设计思想    使用系统调用msgget()msgsnd()msgrev()及msgctl()编制  一长度为B的消息的发送和接收程序。.流程图    .主要程序代码    发送方主要代码:    intmain(intargc,char**argv)    {       intmsqid       structmsgbufbuf       intflag发送消息返回值:成功       intkey创建IPC通讯ftok出的键值       intsendlength发送消息的大小不含消息类型long占用的个字节       key=ftok("msgtmp",x)返回系统建立IPC通讯时需要的ID值       if(key<)       {        perror("ftokkeyerror")        return       }       msqid=msgget(key,|IPCCREAT)创建队列对象并返回标识符       if(msqid<)       {        perror("createmessagequeueerror")       return       }       bufmtype=       strcpy(bufmtext,"ThisisatestofInterProgressConnumation          whichmadebyShiZhongyuwhomajorsinComputingScience          andTechnology,InformationScienceandEngineeringSchool,          ShenYangUniversityofTechnology")       sendlength=sizeof(structmsgbuf)sizeof(long)       flag=msgsnd(msqid,buf,sendlength,)将消息写入到消息列队       if(flag<)       {       perror("sendmessageerror")        return       }      system("ipcsq")  创建子进程执行命令:显示消息队列       return    }    接收方主要代码:    intmain(intargc,char**argv)    {       intmsqid       structmsqiddsinfo       structmsgbufbuf       intflag      intrecvlength       intkey      intmtype       key=ftok("msgtmp",x)返回系统建立IPC通讯时需要的ID值       if(key<)       {         perror("ftokkeyerror")        return       }      msqid=msgget(key,)返回队列标识符       if(msqid<)      {         perror("getipciderror")         return       }      recvlength=sizeof(structmsgbuf)sizeof(long) 接收消息的大小      memset(buf,x,sizeof(structmsgbuf)) 清空buf结构体       mtype=mtype>:接收类型等于发送消息类型的第一个消息       从标识符msqid的队列读取消息存于msgp再删除队列中消息       flag=msgrcv(msqid,buf,recvlength,mtype,)       if(flag<)       {         perror("recvmessageerrorn")         return       }       printf("message:sn", bufmtext)      system("ipcsq")创建子进程执行命令:显示消息队列      return    }.运行结果及分析      先发送消息到已存在的文件msgtmp读取消息后自动删除消息。    再利用ipcrmq(msqid)删除该消息队列。.心得体会    通过本次实验掌握了如何创建消息队列进行进程间通信。题目 利用多进程实现生产者消费者问题.题目的主要研究内容及预期达到的目标    利用多进程实现生产者消费者问题。.题目研究的工作基础或实验条件()硬件环境:Linux平台。()软件环境:标准C语言。.设计思想    创建两个子进程一个子进程(生产者进程)依次向缓冲区写    入整数,,,,另一个子进程(消费者进程)暂停s后从  缓冲区读数每次读一个并将读出的数字从缓冲区删除然后将  数字显示出来父进程等待子进程(消费者进程)的退出信息  待收集到该信息后父进程就返回。.流程图    .主要程序代码    intmain(void)    {      inti=    int*nCount      intfd 打开文件描述符数组fd读fd写      charszBuff={}    int status      pipe(pfd) 先创建管道再创建子进程      while((pid=fork())==)fork()=创建子进程失败      if(pid==)  Child生产者进程      {        nCount=(int*)(malloc(sizeof(int)*)) 分配个字节的内存块        for(i=i<i)        {          nCounti=i          sprintf(szBuff,"sd",szBuff,nCounti) 向szBuff中写入“i”        }        write(fd,szBuff,strlen(szBuff))把szBuff所指的内存到fd的文件        free(nCount)  释放内存块        close(fd)    close(fd)      }      else  pid>      {        while((pid=fork())==)        if(pid==)  Child消费者进程        {         sleep()         read(fd,szBuff,)把fd的文件传送到szBuff指向的内存中         printf("sn",szBuff)         close(fd)    close(fd)        }        else pid>pid>,父进程        {          pid=wait(status)   wait() *同步*          i=WEXITSTATUS(status)          printf("childisd,exitstatus=dn",pid,i)          pid=wait(status)          i=WEXITSTATUS(status)          printf("childisd,exitstatus=dn",pid,i)        }      }      close(fd)    close(fd)      return     }.运行结果及分析        生产者进程依次想缓冲区写入~消费者进程暂停秒后从缓冲区读  数读一个删一个。然后将数字显示出来并打印子进程号。.心得体会    通过本次实验掌握了如何创建消息队列进行模拟生产者消费者问题。总结  通过本次操作系统课程设计掌握了Linux平台下的相关进程通信的知识。以下是自己通过查阅相关文献整理的Linux系统编程的部分学习笔记。  进程间通信类型有:管道、信号、消息队列等。  进程间通信的目的:数据传输、共享数据、通知事件、资源共享、进程控制。  管道是将两个file结构指向同一临时VFS索引节点VFS索引节点指向同一物理页的一种通信方式适用于输入、输出数据量特别大时的父子进程间通信IPC机制所有进程完成管道操作后索引节点被丢弃共享数据页被释放。  通常先用pipe函数创建一个管道再通过fork函数创建一个子进程。  信号的发生由两类事件引起:硬件原因如在终端上按DELETE键产生中断信号SIGINT软件原因如kill、raise、alarm、setitimer等系统函数除的非法运算也会引起信号发送。  进程能对每个信号设置独立的处理方式:能忽略信号也能设置其处理程序(称捕捉)或对信号不做处理执行系统默认动作  进程能通过信号集操作函数设置对信号的阻塞(block)标志信号被设置为阻塞后发生时和正常的信号一样被传送(deliver)给进程但只有进程解除其的阻塞才会被处理。即信号被阻塞后进程不能阻止其的发生仅阻止其不能被处理  从信号被传递给进程到其得到处理的时间间隔称信号挂起、未决或被搁置。  SIGSTOP和SIGKILL信号不能被捕捉、忽略、阻塞保证了系统管理员在任何时候都能暂停信号和杀死信号接收某个进程。  信号分为可靠(信号值在~支持排队)和不可靠信号(信号值小于不支持排队)。  信号的操作方式有:忽略信号、捕捉信号和系统默认动作。消息是在内核地址空间的一个内部链表每个队列都有唯一的标识号。创建消息队列时内核创建、存储及维护着msqidds结构的一个实例。消息队列函数:msgget、msgctl、msgsnd、msgrcv。

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

文档小程序码

使用微信“扫一扫”扫码寻找文档

1

打开微信

2

扫描小程序码

3

发布寻找信息

4

等待寻找结果

我知道了
评分:

/27

可变分区分配与回收——采用最坏算法,操作系统课程设计

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利