




免费预览已结束,剩余16页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
现代操作系统课程设计课程设计报告(论文)报告(论文)题目: PV操作解决生产者-消费者问题 作者所在系部: 计算机科学与工程系 作者所在专业: 网络工程 作者所在班级: * 作 者 姓 名 : * 作 者 学 号 : * 指导教师姓名: * 完 成 时 间 : 2009年11月10日 *目录摘要3第一章 绪论41.1 综述41.2 设计地点41.3 设计目的41.4 设计意义41.5 设计内容41.6 实验环境5第二章 程序设计与实现52.1 详细设计52.1.1 PV操作原理52.1.2生产者消费者问题描述52.1.3 程序流程图72.1.4 调试工具与命令82.1.5关键代码分析8第三章 程序调试与运行93.1编译源文件93.2执行目标文件93.3运行结果103.3.1有PV控制运行结果103.3.2无PV控制运行结果103.4进程的结束113.4.1有PV控制进程结束113.4.2无PV控制进程结束11第四章 总结12参考文献13附录:源程序清单14摘要 进程同步机制的主要任务是对多个机关进程在执行次序上进行协调,使并发执行的诸进程之间能按照一定的规则(或时序)共享系统资源,并能很好的相互合作,从而使程序的执行具有再现性。生产者和消费者是典型的进程同步问题,它说明了进程同步与临界资源的关系。在生产者-消费者问题中,所描述的是生产者生产和消费者消费之间的关系。为使生产者进程与消费者进程并发执行,在两者之间设置了一个具有n个缓冲区的缓冲池。生产者进程将它所生产的产品,按序放入一个缓冲区中。消费者进程也按序从一个缓冲区中取走产品去消费。尽管所有的生产者进程和消费者进程,都是以异步方式运行的,但他们之间必须保持同步关系,即不允许消费者进程到一个空缓冲区中取产品,也不允许生产者进程向一个已装满产品且尚未取走的缓冲区中投放产品。一般来说,信号量S=0时,S表示可用资源的数量。执行一次P操作意味着请求分配一个单位资源,因此S的值减1;当S0时,表示已经没有可用资源,请求者必须等待别的进程释放该类资源,它才能运行下去。而执行一个V操作意味着释放一个单位资源,因此S的值加1;若S=0,表示有某些进程正在等待该资源,因此要唤醒一个等待状态的进程,使之运行下去。多线程就是有两个或两个以上的信号量,线程同步的运行。关键词:生产者 消费者 进程 互斥与同步 临界资源 缓冲区第一章 绪论1.1 综述操作系统是现代计算机系统中最基本和最重要的系统让软件,它是计算机科学与技术专业的一门重要的基础课程。通过讲授本课程,学生可以全面的了解操作系统的概念,操作系统是一组能有效的组织和管理计算机硬件和软件资源,合理地对各类资源进行调度,以方便用户使用的程序的集合。其作用是管理好这些设备,提高利用率和系统的吞吐量,为用户和应用程序提供简单的接口,便于用户使用。学完操作系统,可以更好的搭建学生的专业基础知识。本次课程设计在本着加强课本知识运用能力的前提下,我选取了用PV操作来解决生产者消费者问题这个题目。该题目主要是解决操作系统中进程的同步与互斥的问题。1.2 设计地点图书馆五楼计算机系软二机房1.3 设计目的在Linux下用C语言,调用Linux提供的系统函数编写程序,实现操作系统中生产着与消费者的同步于互斥问题 1.4 设计意义结合操作系统理论课程中学习到的记录型信号量机制,进程的创建、调度、终结方法,在Linux操作系统下进行实际编程模拟操作,完成PV操作解决生产者-消费者问题,使进程能够在系统中有条不紊的运行,从而使大家对可以把理论知识运用到实践中来,加深对理论的理解。1.5 设计内容 设计PV操作算法,用信号量机制实现生产者与消费者同步与互斥问题,并与无PV情况下进行对比。定义20个缓冲区,将其初始化为0。调用随机函数rand()生成随机数,把随机数通过生产者放入缓冲区。若缓冲区满则其值非0。当消费者从缓冲区中去数后缓冲区值变为0。程序可显示缓冲区中的全部内容,方便观察生产者与消费者的行为。程序可通过设置sleep(time)中time的值来控制生产者与消费者的执行顺序。1.6 实验环境Ubuntu 默认桌面环境采用 GNOME(The GNU Network Object Model Environment,GNU网络对象模型环境),一个 UNIX 和 Linux 主流桌面套件和开发平台。第二章 程序设计与实现2.1 详细设计2.1.1 PV操作原理 信号量机制是一种卓有成效的进程同步工具。在长期的广泛应用中,得到了很大的发展,信号量机制已被广泛地应用于但处理机和多处理机系统中。 在记录型信号量中,s.value的初始值表示系统中某资源的数目,因而又成为资源信号量。对它的每次p操作,意味着进程请求一个单位的该资源,使系统中可供分配的该类资源减少一个,因此描述为s.value:=s.value-1;当s.value0时,表示该类资源已分配完毕,因此进程调用block原语,进行自我阻塞,放弃处理机,并插入到信号量链表S.L中。 对信号量的每次v操作,表示执行进程释放一个单元资源,使系统中可供分配的该类资源数增加一个。故s.value:=s.value+1操作表示资源数目加1。若加1后仍是s.value=0,则表示在该信号量链表中,仍有等待该资源的进程被阻塞,故还应调用wakeup原语,将S.L链表中的第一个等待进程唤醒。如果s.value的初始值为1,表示只允许一个进程访问临界资源,此时信号量转化为互斥信号量用于进程互斥。2.1.2生产者消费者问题描述为了实现生产者与消费者同步与互斥的问题,该程序用记录型信号量机制来实现。假定在生产者与消费者之间,利用一个公共的缓冲池来进行通信,生产者将所生产的信息放入其中,消费者cognitive缓冲池中取得消息来消费,该缓冲池具有n个缓冲区,其编号为0,1,2,3,n-1;设置一个互斥信号量mutex,用于实现诸进程对缓冲池的互斥使用,其初值为1,利用资源信号量empty,表示缓冲池中空缓冲区的数目,其初值为n;full分别表示缓冲池中满缓冲区的数目,其初值为0.又假定这些生产者和消费者相互等效,只要缓冲池未满,生产者便可将消息送入由指针in所指的缓冲区;只要缓冲池未空,消费者变可以从由指针out所指示的缓冲区中,取走一个消息。对生产者消费者的问题可以描述如下:Var metux,empty,full:semaphore=1,n,0;Buffer:array0,n-1 of item;In,out:integer:=0;Begin: Pabegin Producer:begin Repeat Producer an item nextp; P(empty);P(mutex); buffer(in):=nextp; in:=(in+1)mod n; V(mutex); V(full);Until false;EndConsumer:begin Repeat P(full);P(mutex); nextc:= buffer(out); out:=(out+1)mod n; V(mutex); V(empty);Until false;EndParendEnd2.1.3 程序流程图创建进程模拟生产者消费者生 产 者消 费 者阻塞N存在空缓冲区有消费请求?Y阻塞阻塞另一生产者正在写?此请求可满足?YN确定产品位置进入临界区阻塞此产品正被消费?从空缓冲区中为本生产者分配一个空间进入临界区(对同一产品进行请求的消费者之间互斥)退出临界区在该缓冲区中写入产品消费产品、并判断是否应该释放产品所占缓冲区通过信号量通知等待本产品的消费者退出临界区结束生产者进程结束消费者进程图 2-1 程序流程图2.1.4 调试工具与命令调试过程中可能用到的命令:启动vi编辑器:vi 文件:q! 不存盘退出。:w 将缓冲区内的资料写入磁盘中,但并不离开vi:q 直接退出。:wq 存盘并退出:wq! 强行存盘退出(相当于ZZ)编译命令:gcc -o 目标文件名源文件名执行命令:./ 目标文件名2.1.5关键代码分析1 信号量操作创建信号量函数 :int semget(key_t key, int nsems, int semflg);控制信号量函数:int semctl(int semid, int semnum, int cmd, union semun arg);PV操作函数: int semop(int semid, struct sembuf * sops, unsigned nsops);信号量的使用是一个很容易出错的问题,如在程序退出时,必须还原所有的加锁,否则程序会运行出错。本系统在缓冲区操作时分为两种情况sem_p(emptyid, 0)之后,如果要写入的缓冲区为空,则执行写入操作然后sem_v (fullid, 0),如果要写入的缓冲区为空,则执行程序不能写入换冲区,要执行还原操作,执行sem_v (emptyid, 0)操作。本程序定义的信号量有emptyid、fullid、mutexid。fullid=semget(IPC_PRIVATE,1,IPC_CREAT|0666); emptyid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);mutexid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);2. 共享内存操作创建共享内存: shmget(char * pathname, int proj_id, size_t size);arrayid=shmget(IPC_PRIVATE,sizeof(int)*MAXSHM,IPC_CREAT|0666);getid=shmget(IPC_PRIVATE,sizeof(int),IPC_CREAT|0666);setid=shmget(IPC_PRIVATE,sizeof(int),IPC_CREAT|0666);删除共享内存: shmctl (char * viraddr, int shmid);本程序定义的共享内存有array、set、get。其中array为20个共享缓冲区,set为多个生产者进程共同的取数端和计数器,get为消费者的计数器。3. 进程操作创建进程函数:fork();进程退出函数:exit (0);这进程等待子进程退出函数:wait (sumert, (int *)0, 0);Main主进程使用fork()生成子进程,这样就生成里一个消费者或生产者进程,并且还为主进程的子进程。当子程序执行了exit(0)第 9 页 共 21 页现代操作系统课程设计第三章 程序调试与运行3.1编译源文件在Linux下编译源文件用命令gcc:如图3-1。图 3-1 编辑命令gcc3.2执行目标文件在Linux先执行目标文件用命令./目标文件。如图3-2。 图 3-2 执行命令./目标文件3.3运行结果 3.3.1有PV控制运行结果有PV控制下的运行结果如图3-3所示图3-3 有PV控制下的运行结果3.3.2无PV控制运行结果无PV控制下的运行结果如图3-4所示图3-4 无PV控制下的运行结果3.4进程的结束 3.4.1有PV控制进程结束有PV控制下的进程结束显示结果如图3-5所示图3-5有PV控制下的进程结束3.4.2无PV控制进程结束无PV控制下的进程结束显示结果如图3-6所示图 3-6无PV控制下进程的结束第四章 总结此次课程设计学习了在C语言里定义信号量、共享内存的使用、用fork()函数创建子进程以及定义信号量的PV操作,并通过sleep函数来调整生产者和消费者对缓冲区的操作,在无PV时初始时让sleep(time)中的time=1可以看到消费者对缓冲区进行读,而此时生产者并无向缓冲区中放东西。在有PV控制下必须是缓冲区非空且无生产者对缓冲区进行操作时消费者才能对缓冲区操作,同理只有缓冲区不满而且无消费者操作时生产者才能对缓冲区操作。通过与无PV控制下对缓冲区进行读写可以进一步理解在信号量控制下的作用。 这次试验让我深刻的了解了操作系统的PV操作,也加深了对操作系统的认识,课本上的概念也有了深入的印象,使我对操作系统这个学科有了整体观感,这次试验,使我受益匪浅,感谢老师的指导和帮助,感谢同学的帮助和关心!参考文献1 汤小丹,梁红兵,哲凤屏,汤子瀛 著。现代操作系统。电子工业出版社,2008年4月2 汤小丹,梁红兵,哲凤屏,汤子瀛 编著。计算机操作系统。现电子科技大学出版社,2007年5月3 计算机操作系统教程清华大学出版社 张尧学附录:源程序清单第 21 页 共 21 页#include#include#include#include#include#include#include#include#define MAX 20 / 定义缓冲区的大小/*定义信号量内部标识*/int emptyid;int fullid;int mutexid;int main() printf(*使用pv操作*n);pv();printf(*无pv操作*n);no_PV();int pv()int i,C1,C2,p1,p2,m; srand(time(NULL);/*定义P、V操作所用的数据结构*/struct sembuf P,V;/*定义给信号量赋初值的参数数据结构*/union semun arg;/*定义共享内存*/int shmid1,shmid2,shmid3;int *buffer,*get,*set;/*创建信号量并初始化*/emptyid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);fullid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);mutexid=semget(IPC_PRIVATE,1,0666|IPC_CREAT); arg.val=1; /*为信号量赋初值*/if(semctl(mutexid,0,SETVAL,arg)=1)perror(semctl setval error);arg.val=20; /*为信号量赋初值*/if(semctl(emptyid,0,SETVAL,arg)=1)perror(semctl setval error);arg.val=0;if(semctl(fullid,0,SETVAL,arg)=1)perror(semctl setval error);/*定义信号量的P操作*/P.sem_num=0;P.sem_op=-1;P.sem_flg=0;/*定义信号量的V操作*/V.sem_num=0;V.sem_op=1;V.sem_flg=0;/*创建并附接共享内存*/shmid1=shmget(IPC_PRIVATE,MAX,0666|IPC_CREAT); buffer=(int*)shmat(shmid1,0,0);for( m=0;mMAX;m+)bufferm=0; /*创建缓冲区信号量buffer、读缓冲区号的计数get以及写缓冲区号的计数set,并初始化*/shmid2=shmget(IPC_PRIVATE,4,0666|IPC_CREAT); set=(int*)shmat(shmid2,0,0);(*set)=0;shmid3=shmget(IPC_PRIVATE,4,0666|IPC_CREAT);get=(int*)shmat(shmid3,0,0);(*get)=0;while(p1=fork()=-1);/创建生产者1子进程直到成功为止,p1存放子进程的pid号if(p1=0) /返回值=0表示子进程返回for(i=0;iMAX;i+) sleep(1);semop(emptyid,&P,1);/对emptyid执行P操作semop(mutexid,&P,1);/对mutexid执行P操作if(*set)MAX)printf(nP1 put data in No.%dn,*set);printf(printf all the data in the buffer :); buffer*set=(rand()%20)+1;for(m=0;mMAX;m+) for(m=0;m=20)break;printf(P1 over!n);exit(0); while(p2=fork()=-1);/创建生产者2子进程直到成功为止,p1存放子进程的pid号if(p2=0) /返回值=0表示子进程返回for(i=0;iMAX;i+)sleep(3);semop(emptyid,&P,1);/对emptyid执行P操作semop(mutexid,&P,1);/对mutexid执行P操作if(*set)MAX)printf(nP2 put data in No.%dn,*set);printf(printf all the data in the buffer :); buffer*set=(rand()%20)+1;for(m=0;m=20)break;sleep(1);printf(P2 over!n);exit(0);while(C1=fork()=-1);/创建消费者1子进程if(C1=0)for(i=0;iMAX;i+)sleep(1);semop(fullid,&P,1);/对fullid执行P操作semop(mutexid,&P,1);if(*get)MAX)printf(nC1 get number from No.%dn,*get);buffer*get=0;printf(printf all the data in the buffer :);for( m=0;m=MAX)break;printf(C1 over!n);exit(0);while(C2=fork()=-1);/创建消费者2子进程if(C2=0)for(i=0;iMAX;i+)sleep(1);semop(fullid,&P,1);/对fullid执行P操作semop(mutexid,&P,1);if(*get)MAX)printf(nC2 get number from No.%dn,*get);buffer*get=0;printf(printf all the data in the buffer :);for( m=0;m=MAX)break;printf(C2 over!n);exit(0);wait(0); /等待子进程终止 wait(0);wait(0);shmdt(buffer); /断开附接的共享内存shmdt(get); /断开附接的共享内存shmdt(set); /断开附接的共享内存 shmctl(shmid1,IPC_RMID,0);/撤消共享内存和信号量集semctl(emptyid,IPC_RMID,0);semctl(fullid,IPC_RMID,0);semctl(mutexid,IPC_RMID,0);wait(0);int no_PV()int i,C1,C2,p1,p2,m;/*定义P、V操作所用的数据结构*/*定义共享内存*/int shmid1,shmid2,shmid3;int *buffer,*get,*set;/*创建并附接共享内存*/shmid1=shmget(IPC_PRIVATE,MAX,0666|IPC_CREAT); buffer=(int*)shmat(shmid1,0,0);for( m=0;mMAX;m+)bufferm=0; /*创建缓冲区信号量buffer、读缓冲区号的计数get以及写缓冲区号的计数set,并初始化*/shmid2=shmget(IPC_PRIVATE,4,0666|IPC_CREAT); set=(int*)shmat(shmid2,0,0);(*set)=0;shmid3=shmget(IPC_PRIVATE,4,0666|IPC_CREAT);get=(int*)shmat(shmid3,0,0);(*get)=0;while(p1=fork()=-1);/创建生产者1子进程直到成功为止,p1存放子进程的pid号if(p1=0) /返回值=0表示子进程返回for(i=0;iMAX;i+)sleep(1);if(*set)MAX)printf(nP1 put data in No.%dn,*set);printf(printf all the data in the buffer :); buffer*set=(rand()%20)+1;for(m=0;mMAX;m+)for( m=0;m=20)break;printf(P1 over!n);exit(0);while(p2=fork()=-1);/创建生产者2子
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2021年人民警察节活动训练学习心得与体会五篇
- 2025年教师招聘之《幼儿教师招聘》题库必背100题含答案详解(精练)
- 教师招聘之《幼儿教师招聘》综合提升测试卷及答案详解(典优)
- 2025年教师招聘之《小学教师招聘》通关提分题库及完整答案详解【各地真题】
- 教师招聘之《幼儿教师招聘》考试彩蛋押题附答案详解【模拟题】
- 教师招聘之《幼儿教师招聘》自测题库及参考答案详解(模拟题)
- 2025年教师招聘之《小学教师招聘》通关提分题库附答案详解【培优】
- 实商务英语综合教程(第一册)-课件 Unit 9 Business Environment
- 2025年新能源商用车辆在电力运输中的应用场景分析报告001
- 教师招聘之《幼儿教师招聘》练习题(一)附参考答案详解【典型题】
- 2025年山东高考真题化学试题(原卷版)
- 2025湖南湘潭市市直事业单位招聘(选调)工作人员48人考试参考试题及答案解析
- 第2课 教师节快乐 第2课时(课件)2025-2026学年道德与法治二年级上册统编版
- 2025年福建省福州市辅警考试题库(附答案)
- 2025年国家网络安全宣传周知识竞赛考试练习题库(完整版)含答案
- 绿化项目养护监理方案投标文件(技术方案)
- 科普短视频与新闻传播融合模式的研究
- 2025滨州市劳动合同范本(示范文本)
- 2025秋新部编版一年级上册语文教学计划+教学进度表
- 大学英语四级高频词汇1500+六级高频词汇1500
- GB/T 20841-2007额定电压300/500V生活设施加热和防结冰用加热电缆
评论
0/150
提交评论