欢迎来到冰点文库! | 帮助中心 分享价值,成长自我!
冰点文库
全部分类
  • 临时分类>
  • IT计算机>
  • 经管营销>
  • 医药卫生>
  • 自然科学>
  • 农林牧渔>
  • 人文社科>
  • 工程科技>
  • PPT模板>
  • 求职职场>
  • 解决方案>
  • 总结汇报>
  • ImageVerifierCode 换一换
    首页 冰点文库 > 资源分类 > DOCX文档下载
    分享到微信 分享到微博 分享到QQ空间

    计算机操作系统课程设计报告《生产者消费者问题》.docx

    • 资源ID:14684326       资源大小:104.74KB        全文页数:17页
    • 资源格式: DOCX        下载积分:1金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录
    二维码
    微信扫一扫登录
    下载资源需要1金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    计算机操作系统课程设计报告《生产者消费者问题》.docx

    1、计算机操作系统课程设计报告生产者消费者问题计算机操作系统课程设计题 目: 生产者-消费者问题 专 业: 软件工程 年 级: 2010级 小组成员: A B 指导教师: 时 间: 地 点: 2012年 5 月摘要生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例。该问题描述了两个共享固定大小缓冲区的线程即所谓的“生产者”和“消费者”在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的

    2、关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。目录1. 概述 42. 课程设计任务及要求 42.1 设计任务 42.2 设计要求 42.3 分工日程表 43. 算法及数据结构 43.1算法的总体思想 43.2 生产者模块 43.3 消费者模块 64. 程序设计与实现 7

    3、4.1 程序流程图 74.2 程序代码 94.3 实验结果 145. 结论 166. 收获、体会和建议 166.1收获 167. 参考文献 171. 概述 本课题设计是完成了“操作系统原理”课程进行的一次全面的综合训练,通过这次课程设计,充分检验学生对课程的掌握程度和熟练情况,让学生更好的掌握操作系统的原理及其实现方法,加深对课程的基础理论和算法的理解,加强学生的动手能力。2. 课程设计任务及要求2.1 设计任务通过研究Linux 的进程机制和信号量实现生产者消费者问题的并发控制.说明:有界缓冲区内设有20个存储单元,放入/取出的数据项设定为1-20这20个整型数。2.2 设计要求(1)每个生

    4、产者和消费者对有界缓冲区进行操作后,实时显示有界缓冲区的全部内容、当前指针位置和生产者/消费者的标识符。(2)生产者和消费者各有两个以上。(3)多个生产者或多个消费者之间须有共享对缓冲区进行操作的函数代码。提示:(1) 有界缓冲区可用数组实现。2.3 分工日程表周三下午周四上午周四下午周五上午周五下午A分析题目讨论,分工编写代码测试系统编写文档B分析题目讨论,分工编写代码添加备注完善系统3. 算法及数据结构3.1算法的总体思想在同一个进程地址空间内执行的两个线程。生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。消费者线程从缓冲区中获得物品,然后释放缓冲区。当生产者线程生产物

    5、品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。3.2 生产者模块3.2.1 功能 在同一个进程地址空间内执行的两个线程。生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。3.2.2 数据结构producer_semaphore/生产者的资源信号量(初始值为缓冲区的大小)Bufferpn /有界缓冲区Pn /缓冲区目标位置MAX_BUFFER/缓冲区上限bu

    6、ffer_mutex/互斥信号量Wait()/等待操作,用于申请资源Signal()/信号操作,用于释放资源Sleep()/挂起3.2.3 算法void *producer_thread(void *tid) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); /* 设置状态,PTHREAD_CANCEL_ENABLE是正常处理cancel信号*/ while(1) sem_wait(&producer_semaphore); /*等待,需要生存*/ srand(int)time(NULL)*(int)tid); sleep(rand()%2

    7、+1); /*一个或两个需要生产*/ while(produce_pointer+1)%20=consume_pointer); /*指针位置*/ sem_wait(&buffer_mutex); /*缓存区*/ bufferproduce_pointer=rand()%20+1; /*指针位置*/ produce_pointer=(produce_pointer+1)%20; /*指针位置*/ /*判断*/ if(produce_pointer=0) printf(生产者:%d 指针指向:%2d 生产产品号:%2dn,(int)tid,19,buffer19); /*输出生产者,指针,缓存区

    8、*/ fprintf(fd,生产者:%d 指针指向:%2d 生产产品号:%2dn,(int)tid,19,buffer19); /*输出生产者,指针,缓存区*/ else printf(生产者:%d 指针指向:%2d 生产产品号:%2dn,(int)tid,produce_pointer-1,bufferproduce_pointer-1);/*输出生产者,指针,缓存区*/ fprintf(fd,生产者:%d 指针指向:%2d 生产产品号:%2dn,(int)tid,produce_pointer-1,bufferproduce_pointer-1);/*输出生产者,指针,缓存区*/ show

    9、buf(); sem_post(&buffer_mutex); sem_post(&consumer_semaphore); /*通知消费者缓冲区不是空的*/ srand(int)time(NULL)*(int)tid); sleep(rand()%5+1); /*等待几秒钟,然后继续生产*/ return (void*)0);3.3 消费者模块3.3.1功能消费者线程从缓冲区中获得物品,然后释放缓冲区。当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。3.3.2 数据结构consumer_semaphore/消费者的资源信号量(初始值为0)Buffe

    10、rpn /有界缓冲区Pn /缓冲区目标位置MAX_BUFFER/缓冲区上限buffer_mutex/互斥信号量Wait()/等待操作,用于申请资源Signal()/信号操作,用于释放资源Sleep()/挂起3.3.3算法void *consumer_thread(void *tid) /*可以被其他线程使用*/ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); /* 设置状态,PTHREAD_CANCEL_ENABLE是忽略cancel信号*/ while(1) sem_wait(&consumer_semaphore); /*通知消费者消

    11、费*/ srand(int)time(NULL)*(int)tid); sleep(rand()%2+1); /*一个或两个来消费*/ sem_wait(&buffer_mutex); printf(消费者:%d 指针指向:%2d 消费产品号:%2dn,(int)tid,consume_pointer,bufferconsume_pointer);/*输出消费者,消费者指针,缓存区*/ fprintf(fd,消费者:%d 指针指向:%2d 消费产品号:%2dn,(int)tid,consume_pointer,bufferconsume_pointer);/*输出消费者,消费者指针,缓存区*/

    12、 bufferconsume_pointer=0; /*消费者指针指向0*/ consume_pointer=(consume_pointer+1)%20; showbuf(); sem_post(&buffer_mutex); sem_post(&producer_semaphore); /*通知生产者缓冲区不是空的*/ srand(int)time(NULL)*(int)tid); sleep(rand()%5+1); /*等待几秒钟,然后继续消费*/ return (void*)0);4. 程序设计与实现4.1 程序流程图4.2 程序代码#include#include#include#

    13、include#include#include#include#include#include#include#define NUM_THREADS_P 5 /*定义数据为生产者*/#define NUM_THREADS_C 5 /*定义数据为消费者*/#define MAX_BUFFER 20 /*定义数据为缓存区*/#define RUN_TIME 20 /*定义运行时间*/int bufferMAX_BUFFER; /*定义最大缓存区*/int produce_pointer=0,consume_pointer=0; /*定义指针*/sem_t producer_semaphore,co

    14、nsumer_semaphore,buffer_mutex; /*定义信号量,互斥*/pthread_t threads_pNUM_THREADS_P; /*声明生产者线程*/pthread_t threads_cNUM_THREADS_C; /*声明消费者线程*/FILE* fd; void *producer_thread(void *tid); /*声明生产者线程*/void *consumer_thread(void *tid); /*声明消费者线程*/void showbuf(); /*声明showbuf方法*/void handler() int i; /*定义i*/ for(i=

    15、0;iNUM_THREADS_P;i+) pthread_cancel(threads_pi); /*for循环,如果iNUM_THREADS_P,则pthread_cancel(threads_pi);并且i+*/ for(i=0;iNUM_THREADS_C;i+) pthread_cancel(threads_ci);/*for循环,如果iNUM_THREADS_C,则pthread_cancel(threads_ci);并且i+*/int main() int i; /*定义i*/ signal(SIGALRM,handler); /*定义信号量*/ fd=fopen(output.t

    16、xt,w); /*打开一个文件用来保存结果*/ sem_init(&producer_semaphore,0,MAX_BUFFER); /*放一个值给信号灯*/ sem_init(&consumer_semaphore,0,0); sem_init(&buffer_mutex,0,1); for(i=0;iMAX_BUFFER;i+) bufferi=0; /*引发缓冲*/ /*创建线程*/ for(i=0;iNUM_THREADS_P;i+) pthread_create(&threads_pi,NULL,(void*)producer_thread,(void*)(i+1); /*创建线程

    17、*/ for(i=0;iNUM_THREADS_C;i+) pthread_create(&threads_ci,NULL,(void*)consumer_thread,(void *)(i+1); alarm(RUN_TIME); for(i=0;iNUM_THREADS_P;i+) pthread_join(threads_pi,NULL);/*等待线程退出*/ for(i=0;iNUM_THREADS_C;i+) pthread_join(threads_ci,NULL);/*等待线程退出*/ sem_destroy(&producer_semaphore); /*清除信号灯*/ sem

    18、_destroy(&consumer_semaphore); /*清除信号灯*/ sem_destroy(&buffer_mutex);/*清除缓存区*/ fclose(fd); /*关闭文件*/ return 0;void *producer_thread(void *tid) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); /* 设置状态,PTHREAD_CANCEL_ENABLE是正常处理cancel信号*/ while(1) sem_wait(&producer_semaphore); /*等待,需要生存*/ srand(int)

    19、time(NULL)*(int)tid); sleep(rand()%2+1); /*一个或两个需要生产*/ while(produce_pointer+1)%20=consume_pointer); /*指针位置*/ sem_wait(&buffer_mutex); /*缓存区*/ bufferproduce_pointer=rand()%20+1; /*指针位置*/ produce_pointer=(produce_pointer+1)%20; /*指针位置*/ /*判断*/ if(produce_pointer=0) printf(生产者:%d 指针指向:%2d 生产产品号:%2dn,(

    20、int)tid,19,buffer19); /*输出生产者,指针,缓存区*/ fprintf(fd,生产者:%d 指针指向:%2d 生产产品号:%2dn,(int)tid,19,buffer19); /*输出生产者,指针,缓存区*/ else printf(生产者:%d 指针指向:%2d 生产产品号:%2dn,(int)tid,produce_pointer-1,bufferproduce_pointer-1);/*输出生产者,指针,缓存区*/ fprintf(fd,生产者:%d 指针指向:%2d 生产产品号:%2dn,(int)tid,produce_pointer-1,bufferprod

    21、uce_pointer-1);/*输出生产者,指针,缓存区*/ showbuf(); sem_post(&buffer_mutex); sem_post(&consumer_semaphore); /*通知消费者缓冲区不是空的*/ srand(int)time(NULL)*(int)tid); sleep(rand()%5+1); /*等待几秒钟,然后继续生产*/ return (void*)0);void *consumer_thread(void *tid) /*可以被其他线程使用*/ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);

    22、/* 设置状态,PTHREAD_CANCEL_ENABLE是忽略cancel信号*/ while(1) sem_wait(&consumer_semaphore); /*通知消费者消费*/ srand(int)time(NULL)*(int)tid); sleep(rand()%2+1); /*一个或两个来消费*/ sem_wait(&buffer_mutex); printf(消费者:%d 指针指向:%2d 消费产品号:%2dn,(int)tid,consume_pointer,bufferconsume_pointer);/*输出消费者,消费者指针,缓存区*/ fprintf(fd,消费者

    23、:%d 指针指向:%2d 消费产品号:%2dn,(int)tid,consume_pointer,bufferconsume_pointer);/*输出消费者,消费者指针,缓存区*/ bufferconsume_pointer=0; /*消费者指针指向0*/ consume_pointer=(consume_pointer+1)%20; showbuf(); sem_post(&buffer_mutex); sem_post(&producer_semaphore); /*通知生产者缓冲区不是空的*/ srand(int)time(NULL)*(int)tid); sleep(rand()%5

    24、+1); /*等待几秒钟,然后继续消费*/ return (void*)0);/*查看缓冲区内容*/void showbuf() int i; /*定义i*/ printf(buffer:); /*输出缓存区*/ fprintf(fd,buffer:); /*输出缓存区*/ for(i=0;iMAX_BUFFER;i+) printf(%2d ,bufferi);/*输出缓存区i*/ fprintf(fd,%2d ,bufferi); /*输出缓存区i*/ printf(nn); /*换行*/ fprintf(fd,nn); /*换行*/4.3 实验结果5. 结论本次课程设计主要是对操作系统中

    25、线程,进程同步互斥等知识的揉合应用,生产者-消费者问题是一个著名的同步问题,原理易懂,但操作并不简单。本次编写的程序基本实现了设计要求的功能,但并没有做到真正的完善,系统还有一点小瑕疵,对于某些方面的小问题没有能解决。但这次课程设计通过我们组员的努力还是基本完成了,对于自身的帮助非常大,无论是编写程序还是设计等各方面都有很大的提升。6. 收获、体会和建议A: 经过2.5天的课程设计,我们完成了一个生产者-消费者问题的小程序,这个程序主要考察的是是P、V操作,实验设一个共享缓冲区,生产者和消费者互斥的使用,当一个线程使用缓冲区的时候,另一个让其等待直到前一个线程释放缓冲区为止。还有就是对进程,线

    26、程的操作。实话说这部分的代码在编写的时候确实给我们带来了不少的麻烦,但在查阅了一些书籍,网上资料,还有请教了别人以后,还是成功的通过了验证,达到的预期的效果。这次课程设计锻炼了我的动手能力,强化了我的编码能力,同时加深了我对操作系统这门课程的理解,尤其是基本的概念和重要算法这部分的内容,对我影响非常大,p,v操作的实质和重要性,同一个缓冲区内不同进程的操作,互斥信号量的运用。这次课程设计不但加深了对操作系统这们课程的认识,而且还了解了操作系统中使用信号量解决生产者消费者问题算法的实现。比如:用信号量解决生产者消费者问题时,可以通过一个有界缓冲区(用数组来实现,类似循环队列)把生产者和消费者联系

    27、起来。最后感谢老师的教导和组员的通力合作!B: 我们这次课程设计的课题是生产者-消费者问题,虽然时间只有2.5天,但是经过上学期期末的课程设计,我们都有了一定的经验,效率也提高了很多。当我们组拿到题目的时候我们先对题目进行分析,然后进行下一步操作,比如,到图书馆借相关的资料,到网上搜索等等,最终经过我们组的努力以及向老师和同学请求帮助下顺利的实现了其中的功能。 我认为,在这次课程设计中,不仅培养了独立思考、动手操作的能力,在各种其它能力上也都有了提高。更重要的是,在实验课上,我们学会了很多学习的方法。而这是以后最实用的,真的是受益匪浅。要面对社会的挑战,只有不断的学习、实践,再学习、再实践。这

    28、对于我们的将来也有很大的帮助。回顾起此课程设计,至今我仍感慨颇多,从理论到实践,在这段日子里,可以说得是苦多于甜,但是可以学到很多很多的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,从而提高自己的实际动手能力和独立思考的能力。此次设计也让我明白了思路即出路,有什么不懂不明白的地方要及时请教或上网查询,只要认真钻研,动脑思考,动手实践,就没有弄不懂的知识,收获颇丰。7. 参考文献1 汤小丹,梁红兵,哲凤屏,汤子瀛计算机操作系统M西安:电子科技大学出版社,2005。2 XX文库


    注意事项

    本文(计算机操作系统课程设计报告《生产者消费者问题》.docx)为本站会员主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    copyright@ 2008-2023 冰点文库 网站版权所有

    经营许可证编号:鄂ICP备19020893号-2


    收起
    展开